From e5ef7288f462e2b6e172497650abef534edc15b0 Mon Sep 17 00:00:00 2001 From: xuhuixiang Date: Mon, 13 Mar 2023 10:07:44 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=AC=E4=B8=80=E6=AC=A1=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 16 + README.md | 88 +- app/.gitignore | 1 + app/.idea/.gitignore | 3 + app/.idea/gradle.xml | 12 + app/.idea/misc.xml | 9 + app/.idea/modules.xml | 8 + app/.idea/vcs.xml | 6 + app/build.gradle | 112 +++ app/proguard-rules.pro | 451 +++++++++ .../cleanmark/ExampleInstrumentedTest.java | 26 + app/src/main/AndroidManifest.xml | 73 ++ .../main/java/com/dskj/daikuan/InitApp.java | 156 +++ .../com/dskj/daikuan/adapter/BaseAdapter.java | 68 ++ .../daikuan/adapter/CommunityAdapter.java | 34 + .../dskj/daikuan/adapter/GoodsAdapter.java | 34 + .../daikuan/adapter/comm/CommonAdapter.java | 70 ++ .../dskj/daikuan/adapter/comm/ViewHolder.java | 60 ++ .../main/java/com/dskj/daikuan/api/Api.java | 76 ++ .../java/com/dskj/daikuan/api/ApiService.java | 42 + .../com/dskj/daikuan/api/BaseObserver.java | 114 +++ .../dskj/daikuan/api/HeaderInterceptor.java | 28 + .../java/com/dskj/daikuan/api/Result.java | 30 + .../com/dskj/daikuan/bean/ErrorMesage.java | 31 + .../com/dskj/daikuan/bean/MemberOrder.java | 158 +++ .../java/com/dskj/daikuan/bean/UserBean.java | 158 +++ .../java/com/dskj/daikuan/bean/VideoBean.java | 98 ++ .../com/dskj/daikuan/bean/VideoIndexBean.java | 64 ++ .../dskj/daikuan/bean/VideoIndexResult.java | 16 + .../com/dskj/daikuan/bean/VideoResult.java | 43 + .../java/com/dskj/daikuan/config/Config.java | 45 + .../daikuan/ui/activity/LoginActivity.java | 145 +++ .../daikuan/ui/activity/MainActivity.java | 133 +++ .../daikuan/ui/activity/ShenQingActivity.java | 416 ++++++++ .../daikuan/ui/activity/StartUpActivity.java | 95 ++ .../ui/activity/XiangQingActivity.java | 50 + .../ui/dialog/SwitchVideoTypeDialog.java | 76 ++ .../daikuan/ui/view/BezierCircleHeader.java | 364 +++++++ .../dskj/daikuan/ui/view/CircleImageView.java | 323 +++++++ .../daikuan/ui/view/NestedScrollableHost.java | 145 +++ .../dskj/daikuan/ui/view/StatusLayout.java | 44 + .../dskj/daikuan/utils/AppContextUtil.java | 22 + .../daikuan/utils/CenterAlignImageSpan.java | 33 + .../com/dskj/daikuan/utils/DeviceUtil.java | 83 ++ .../com/dskj/daikuan/utils/FileUtils.java | 905 ++++++++++++++++++ .../com/dskj/daikuan/utils/GsonUtils.java | 90 ++ .../java/com/dskj/daikuan/utils/LogUtils.java | 146 +++ .../java/com/dskj/daikuan/utils/RxBus.java | 53 + .../com/dskj/daikuan/utils/ToastUtils.java | 10 + .../daikuan/viewModel/home/MainViewModel.java | 118 +++ .../viewModel/home/SwitchVideoModel.java | 39 + .../transfer/ProgressBarIndicatorNew.java | 69 ++ .../tilibrary/transfer/TransfereeNew.java | 276 ++++++ app/src/main/res/anim/animate.xml | 7 + .../res/anim/item_animation_fall_down.xml | 20 + app/src/main/res/color/select_color.xml | 7 + app/src/main/res/color/select_color1.xml | 7 + .../drawable-v24/ic_launcher_foreground.xml | 30 + app/src/main/res/drawable/actionbar_bg.xml | 7 + app/src/main/res/drawable/bg_ripple.xml | 6 + .../main/res/drawable/dlg_input_video_bg.xml | 9 + .../res/drawable/ic_launcher_background.xml | 170 ++++ app/src/main/res/drawable/inputbg.xml | 25 + app/src/main/res/drawable/inputbg_false.xml | 25 + app/src/main/res/drawable/inputbg_true.xml | 25 + app/src/main/res/drawable/item_bg_default.xml | 25 + .../main/res/drawable/item_bg_default1.xml | 25 + .../res/drawable/jz_bottom_seek_progress.xml | 28 + app/src/main/res/drawable/jz_seek_post.xml | 9 + app/src/main/res/drawable/save_btn_back.xml | 5 + app/src/main/res/drawable/search_bg.xml | 19 + app/src/main/res/drawable/tab_line.xml | 32 + app/src/main/res/drawable/tab_line1.xml | 15 + app/src/main/res/layout/activity_login.xml | 120 +++ app/src/main/res/layout/activity_main2.xml | 103 ++ app/src/main/res/layout/activity_shenqing.xml | 361 +++++++ app/src/main/res/layout/activity_start_up.xml | 38 + .../main/res/layout/activity_xiangqing.xml | 353 +++++++ app/src/main/res/layout/agent_child_item.xml | 64 ++ .../main/res/layout/layout_action_bar1.xml | 49 + app/src/main/res/layout/layout_custom.xml | 43 + .../main/res/layout/switch_video_dialog.xml | 18 + .../res/layout/switch_video_dialog_item.xml | 14 + .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + app/src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1404 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 2898 bytes app/src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 982 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 1772 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1900 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 3918 bytes .../res/mipmap-xhdpi/more_live_right_img.png | Bin 0 -> 1198 bytes app/src/main/res/mipmap-xxhdpi/add_img.png | Bin 0 -> 2042 bytes app/src/main/res/mipmap-xxhdpi/edit_false.png | Bin 0 -> 4988 bytes app/src/main/res/mipmap-xxhdpi/edit_true.png | Bin 0 -> 4650 bytes .../main/res/mipmap-xxhdpi/ic_black_back.png | Bin 0 -> 1180 bytes .../res/mipmap-xxhdpi/ic_black_back_white.png | Bin 0 -> 1509 bytes app/src/main/res/mipmap-xxhdpi/login_bot.png | Bin 0 -> 99809 bytes app/src/main/res/mipmap-xxhdpi/logo_img.png | Bin 0 -> 16878 bytes app/src/main/res/mipmap-xxhdpi/nodate_img.png | Bin 0 -> 9022 bytes app/src/main/res/mipmap-xxhdpi/select_img.png | Bin 0 -> 915 bytes app/src/main/res/mipmap-xxhdpi/sese.png | Bin 0 -> 135769 bytes .../main/res/mipmap-xxhdpi/sfz_add_img.png | Bin 0 -> 4817 bytes app/src/main/res/mipmap-xxhdpi/sfzbm.png | Bin 0 -> 10629 bytes app/src/main/res/mipmap-xxhdpi/sfzzm.png | Bin 0 -> 9104 bytes app/src/main/res/mipmap-xxhdpi/top_bg.png | Bin 0 -> 48097 bytes .../main/res/mipmap-xxxhdpi/new_bg_index.png | Bin 0 -> 270381 bytes app/src/main/res/values-night/colors.xml | 76 ++ app/src/main/res/values-night/themes.xml | 16 + app/src/main/res/values-zh/values-zh.xml | 4 + app/src/main/res/values/colors.xml | 77 ++ app/src/main/res/values/dimens.xml | 116 +++ app/src/main/res/values/font_certs.xml | 17 + app/src/main/res/values/ids.xml | 11 + app/src/main/res/values/strings.xml | 11 + app/src/main/res/values/themes.xml | 823 ++++++++++++++++ app/src/main/res/xml/file_paths.xml | 9 + app/src/main/res/xml/file_paths_csj.xml | 9 + app/src/main/res/xml/gdt_file_path.xml | 10 + .../main/res/xml/network_security_config.xml | 4 + .../com/bikao/cleanmark/ExampleUnitTest.java | 17 + app/videomark.jks | Bin 0 -> 2621 bytes basicLib/.gitignore | 1 + basicLib/build.gradle | 58 ++ basicLib/proguard-rules.pro | 22 + basicLib/src/main/AndroidManifest.xml | 2 + .../azhon/basic/adapter/BaseDBRVAdapter.java | 132 +++ .../azhon/basic/adapter/BaseDBRVHolder.java | 22 + .../basic/adapter/OnItemClickListener.java | 31 + .../com/azhon/basic/base/BaseActivity.java | 70 ++ .../com/azhon/basic/base/BaseFragment.java | 105 ++ .../azhon/basic/base/BaseLazyFragment.java | 36 + .../azhon/basic/base/BaseNoModelActivity.java | 328 +++++++ .../azhon/basic/base/BaseNoModelFragment.java | 180 ++++ .../java/com/azhon/basic/bean/DialogBean.java | 33 + .../azhon/basic/lifecycle/BaseViewModel.java | 69 ++ .../azhon/basic/lifecycle/DialogLiveData.java | 32 + .../com/azhon/basic/retrofit/BaseApi.java | 46 + .../com/azhon/basic/utils/ActivityUtil.java | 92 ++ .../java/com/azhon/basic/utils/AnimUtil.java | 26 + .../java/com/azhon/basic/utils/ApkUtil.java | 76 ++ .../com/azhon/basic/utils/DensityUtil.java | 83 ++ .../com/azhon/basic/utils/SharePreUtil.java | 144 +++ .../com/azhon/basic/utils/SnackbarUtils.java | 475 +++++++++ .../java/com/azhon/basic/utils/TimeUtil.java | 117 +++ .../com/azhon/basic/view/LoadingDialog.java | 57 ++ .../main/res/drawable/dialog_loading_bg.xml | 5 + .../src/main/res/layout/dialog_loading.xml | 33 + basicLib/src/main/res/values/strings.xml | 3 + basicLib/src/main/res/values/styles.xml | 21 + build.gradle | 69 ++ gradle.properties | 28 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 6 + matisse/.gitignore | 1 + matisse/build.gradle | 70 ++ matisse/gradle.properties | 0 matisse/proguard-rules.pro | 19 + matisse/src/main/AndroidManifest.xml | 30 + .../main/java/com/zhihu/matisse/Matisse.java | 161 ++++ .../main/java/com/zhihu/matisse/MimeType.java | 178 ++++ .../com/zhihu/matisse/SelectionCreator.java | 377 ++++++++ .../com/zhihu/matisse/engine/ImageEngine.java | 82 ++ .../matisse/engine/impl/GlideEngine.java | 87 ++ .../matisse/engine/impl/PicassoEngine.java | 61 ++ .../java/com/zhihu/matisse/filter/Filter.java | 69 ++ .../zhihu/matisse/internal/entity/Album.java | 122 +++ .../internal/entity/CaptureStrategy.java | 33 + .../internal/entity/IncapableCause.java | 83 ++ .../zhihu/matisse/internal/entity/Item.java | 144 +++ .../internal/entity/SelectionSpec.java | 121 +++ .../matisse/internal/loader/AlbumLoader.java | 293 ++++++ .../internal/loader/AlbumMediaLoader.java | 197 ++++ .../internal/model/AlbumCollection.java | 114 +++ .../internal/model/AlbumMediaCollection.java | 107 +++ .../model/SelectedItemCollection.java | 277 ++++++ .../internal/ui/AlbumPreviewActivity.java | 97 ++ .../internal/ui/BasePreviewActivity.java | 351 +++++++ .../internal/ui/MediaSelectionFragment.java | 159 +++ .../internal/ui/PreviewItemFragment.java | 123 +++ .../internal/ui/SelectedPreviewActivity.java | 51 + .../ui/adapter/AlbumMediaAdapter.java | 297 ++++++ .../internal/ui/adapter/AlbumsAdapter.java | 71 ++ .../ui/adapter/PreviewPagerAdapter.java | 70 ++ .../ui/adapter/RecyclerViewCursorAdapter.java | 105 ++ .../internal/ui/widget/AlbumsSpinner.java | 120 +++ .../internal/ui/widget/CheckRadioView.java | 60 ++ .../matisse/internal/ui/widget/CheckView.java | 229 +++++ .../internal/ui/widget/IncapableDialog.java | 59 ++ .../matisse/internal/ui/widget/MediaGrid.java | 161 ++++ .../internal/ui/widget/MediaGridInset.java | 60 ++ .../internal/ui/widget/PreviewViewPager.java | 38 + .../ui/widget/RoundedRectangleImageView.java | 65 ++ .../internal/ui/widget/SquareFrameLayout.java | 36 + .../internal/utils/ExifInterfaceCompat.java | 131 +++ .../internal/utils/MediaStoreCompat.java | 145 +++ .../matisse/internal/utils/PathUtils.java | 135 +++ .../internal/utils/PhotoMetadataUtils.java | 178 ++++ .../matisse/internal/utils/Platform.java | 16 + .../internal/utils/SingleMediaScanner.java | 44 + .../zhihu/matisse/internal/utils/UIUtils.java | 32 + .../matisse/listener/OnCheckedListener.java | 9 + .../OnFragmentInteractionListener.java | 11 + .../matisse/listener/OnSelectedListener.java | 30 + .../com/zhihu/matisse/ui/MatisseActivity.java | 456 +++++++++ .../color/dracula_bottom_toolbar_apply.xml | 21 + .../color/dracula_bottom_toolbar_preview.xml | 21 + .../dracula_preview_bottom_toolbar_apply.xml | 21 + .../res/color/zhihu_bottom_toolbar_apply.xml | 21 + .../color/zhihu_bottom_toolbar_preview.xml | 21 + .../zhihu_preview_bottom_toolbar_apply.xml | 21 + .../ic_arrow_drop_down_white_24dp.png | Bin 0 -> 123 bytes .../res/drawable-hdpi/ic_check_white_18dp.png | Bin 0 -> 152 bytes .../res/drawable-hdpi/ic_empty_dracula.png | Bin 0 -> 5911 bytes .../main/res/drawable-hdpi/ic_empty_zhihu.png | Bin 0 -> 5785 bytes matisse/src/main/res/drawable-hdpi/ic_gif.png | Bin 0 -> 929 bytes .../ic_play_circle_outline_white_48dp.png | Bin 0 -> 1023 bytes .../drawable-hdpi/ic_preview_radio_off.webp | Bin 0 -> 290 bytes .../drawable-hdpi/ic_preview_radio_on.webp | Bin 0 -> 338 bytes .../ic_arrow_drop_down_white_24dp.png | Bin 0 -> 95 bytes .../res/drawable-mdpi/ic_check_white_18dp.png | Bin 0 -> 146 bytes .../res/drawable-mdpi/ic_empty_dracula.png | Bin 0 -> 4018 bytes .../main/res/drawable-mdpi/ic_empty_zhihu.png | Bin 0 -> 3843 bytes matisse/src/main/res/drawable-mdpi/ic_gif.png | Bin 0 -> 638 bytes .../ic_play_circle_outline_white_48dp.png | Bin 0 -> 699 bytes .../drawable-mdpi/ic_preview_radio_off.webp | Bin 0 -> 410 bytes .../drawable-mdpi/ic_preview_radio_on.webp | Bin 0 -> 486 bytes .../ic_arrow_drop_down_white_24dp.png | Bin 0 -> 120 bytes .../drawable-xhdpi/ic_check_white_18dp.png | Bin 0 -> 181 bytes .../res/drawable-xhdpi/ic_empty_dracula.png | Bin 0 -> 8159 bytes .../res/drawable-xhdpi/ic_empty_zhihu.png | Bin 0 -> 7977 bytes .../src/main/res/drawable-xhdpi/ic_gif.png | Bin 0 -> 993 bytes .../ic_play_circle_outline_white_48dp.png | Bin 0 -> 1379 bytes .../drawable-xhdpi/ic_preview_radio_off.webp | Bin 0 -> 544 bytes .../drawable-xhdpi/ic_preview_radio_on.webp | Bin 0 -> 644 bytes .../ic_arrow_drop_down_white_24dp.png | Bin 0 -> 152 bytes .../res/drawable-xxhdpi/ic_black_back.png | Bin 0 -> 1062 bytes .../drawable-xxhdpi/ic_check_white_18dp.png | Bin 0 -> 236 bytes .../res/drawable-xxhdpi/ic_empty_dracula.png | Bin 0 -> 13087 bytes .../res/drawable-xxhdpi/ic_empty_zhihu.png | Bin 0 -> 12785 bytes .../src/main/res/drawable-xxhdpi/ic_gif.png | Bin 0 -> 1380 bytes .../ic_play_circle_outline_white_48dp.png | Bin 0 -> 2145 bytes .../ic_arrow_drop_down_white_24dp.png | Bin 0 -> 185 bytes .../drawable-xxxhdpi/ic_check_white_18dp.png | Bin 0 -> 276 bytes .../res/drawable-xxxhdpi/ic_empty_dracula.png | Bin 0 -> 17923 bytes .../res/drawable-xxxhdpi/ic_empty_zhihu.png | Bin 0 -> 17553 bytes .../src/main/res/drawable-xxxhdpi/ic_gif.png | Bin 0 -> 1712 bytes .../ic_photo_camera_white_24dp.png | Bin 0 -> 894 bytes .../ic_play_circle_outline_white_48dp.png | Bin 0 -> 2836 bytes .../src/main/res/layout/activity_matisse.xml | 150 +++ .../res/layout/activity_media_preview.xml | 130 +++ .../src/main/res/layout/album_list_item.xml | 57 ++ .../res/layout/fragment_media_selection.xml | 31 + .../main/res/layout/fragment_preview_item.xml | 32 + .../main/res/layout/media_grid_content.xml | 50 + .../src/main/res/layout/media_grid_item.xml | 21 + .../main/res/layout/photo_capture_item.xml | 36 + .../src/main/res/values-zh-rTW/strings.xml | 38 + matisse/src/main/res/values-zh/strings.xml | 40 + matisse/src/main/res/values/attrs.xml | 36 + matisse/src/main/res/values/colors.xml | 22 + .../src/main/res/values/colors_dracula.xml | 43 + matisse/src/main/res/values/colors_zhihu.xml | 45 + matisse/src/main/res/values/dimens.xml | 22 + matisse/src/main/res/values/strings.xml | 43 + matisse/src/main/res/values/styles.xml | 125 +++ settings.gradle | 5 + 267 files changed, 17967 insertions(+), 86 deletions(-) create mode 100644 .gitignore create mode 100644 app/.gitignore create mode 100644 app/.idea/.gitignore create mode 100644 app/.idea/gradle.xml create mode 100644 app/.idea/misc.xml create mode 100644 app/.idea/modules.xml create mode 100644 app/.idea/vcs.xml create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/com/bikao/cleanmark/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/dskj/daikuan/InitApp.java create mode 100644 app/src/main/java/com/dskj/daikuan/adapter/BaseAdapter.java create mode 100644 app/src/main/java/com/dskj/daikuan/adapter/CommunityAdapter.java create mode 100644 app/src/main/java/com/dskj/daikuan/adapter/GoodsAdapter.java create mode 100644 app/src/main/java/com/dskj/daikuan/adapter/comm/CommonAdapter.java create mode 100644 app/src/main/java/com/dskj/daikuan/adapter/comm/ViewHolder.java create mode 100644 app/src/main/java/com/dskj/daikuan/api/Api.java create mode 100644 app/src/main/java/com/dskj/daikuan/api/ApiService.java create mode 100644 app/src/main/java/com/dskj/daikuan/api/BaseObserver.java create mode 100644 app/src/main/java/com/dskj/daikuan/api/HeaderInterceptor.java create mode 100644 app/src/main/java/com/dskj/daikuan/api/Result.java create mode 100644 app/src/main/java/com/dskj/daikuan/bean/ErrorMesage.java create mode 100644 app/src/main/java/com/dskj/daikuan/bean/MemberOrder.java create mode 100644 app/src/main/java/com/dskj/daikuan/bean/UserBean.java create mode 100644 app/src/main/java/com/dskj/daikuan/bean/VideoBean.java create mode 100644 app/src/main/java/com/dskj/daikuan/bean/VideoIndexBean.java create mode 100644 app/src/main/java/com/dskj/daikuan/bean/VideoIndexResult.java create mode 100644 app/src/main/java/com/dskj/daikuan/bean/VideoResult.java create mode 100644 app/src/main/java/com/dskj/daikuan/config/Config.java create mode 100644 app/src/main/java/com/dskj/daikuan/ui/activity/LoginActivity.java create mode 100644 app/src/main/java/com/dskj/daikuan/ui/activity/MainActivity.java create mode 100644 app/src/main/java/com/dskj/daikuan/ui/activity/ShenQingActivity.java create mode 100644 app/src/main/java/com/dskj/daikuan/ui/activity/StartUpActivity.java create mode 100644 app/src/main/java/com/dskj/daikuan/ui/activity/XiangQingActivity.java create mode 100644 app/src/main/java/com/dskj/daikuan/ui/dialog/SwitchVideoTypeDialog.java create mode 100644 app/src/main/java/com/dskj/daikuan/ui/view/BezierCircleHeader.java create mode 100644 app/src/main/java/com/dskj/daikuan/ui/view/CircleImageView.java create mode 100644 app/src/main/java/com/dskj/daikuan/ui/view/NestedScrollableHost.java create mode 100644 app/src/main/java/com/dskj/daikuan/ui/view/StatusLayout.java create mode 100644 app/src/main/java/com/dskj/daikuan/utils/AppContextUtil.java create mode 100644 app/src/main/java/com/dskj/daikuan/utils/CenterAlignImageSpan.java create mode 100644 app/src/main/java/com/dskj/daikuan/utils/DeviceUtil.java create mode 100644 app/src/main/java/com/dskj/daikuan/utils/FileUtils.java create mode 100644 app/src/main/java/com/dskj/daikuan/utils/GsonUtils.java create mode 100644 app/src/main/java/com/dskj/daikuan/utils/LogUtils.java create mode 100644 app/src/main/java/com/dskj/daikuan/utils/RxBus.java create mode 100644 app/src/main/java/com/dskj/daikuan/utils/ToastUtils.java create mode 100644 app/src/main/java/com/dskj/daikuan/viewModel/home/MainViewModel.java create mode 100644 app/src/main/java/com/dskj/daikuan/viewModel/home/SwitchVideoModel.java create mode 100644 app/src/main/java/com/hitomi/tilibrary/transfer/ProgressBarIndicatorNew.java create mode 100644 app/src/main/java/com/hitomi/tilibrary/transfer/TransfereeNew.java create mode 100644 app/src/main/res/anim/animate.xml create mode 100644 app/src/main/res/anim/item_animation_fall_down.xml create mode 100644 app/src/main/res/color/select_color.xml create mode 100644 app/src/main/res/color/select_color1.xml create mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/actionbar_bg.xml create mode 100644 app/src/main/res/drawable/bg_ripple.xml create mode 100644 app/src/main/res/drawable/dlg_input_video_bg.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/drawable/inputbg.xml create mode 100644 app/src/main/res/drawable/inputbg_false.xml create mode 100644 app/src/main/res/drawable/inputbg_true.xml create mode 100644 app/src/main/res/drawable/item_bg_default.xml create mode 100644 app/src/main/res/drawable/item_bg_default1.xml create mode 100644 app/src/main/res/drawable/jz_bottom_seek_progress.xml create mode 100644 app/src/main/res/drawable/jz_seek_post.xml create mode 100644 app/src/main/res/drawable/save_btn_back.xml create mode 100644 app/src/main/res/drawable/search_bg.xml create mode 100644 app/src/main/res/drawable/tab_line.xml create mode 100644 app/src/main/res/drawable/tab_line1.xml create mode 100644 app/src/main/res/layout/activity_login.xml create mode 100644 app/src/main/res/layout/activity_main2.xml create mode 100644 app/src/main/res/layout/activity_shenqing.xml create mode 100644 app/src/main/res/layout/activity_start_up.xml create mode 100644 app/src/main/res/layout/activity_xiangqing.xml create mode 100644 app/src/main/res/layout/agent_child_item.xml create mode 100644 app/src/main/res/layout/layout_action_bar1.xml create mode 100644 app/src/main/res/layout/layout_custom.xml create mode 100644 app/src/main/res/layout/switch_video_dialog.xml create mode 100644 app/src/main/res/layout/switch_video_dialog_item.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xhdpi/more_live_right_img.png create mode 100644 app/src/main/res/mipmap-xxhdpi/add_img.png create mode 100644 app/src/main/res/mipmap-xxhdpi/edit_false.png create mode 100644 app/src/main/res/mipmap-xxhdpi/edit_true.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_black_back.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_black_back_white.png create mode 100644 app/src/main/res/mipmap-xxhdpi/login_bot.png create mode 100644 app/src/main/res/mipmap-xxhdpi/logo_img.png create mode 100644 app/src/main/res/mipmap-xxhdpi/nodate_img.png create mode 100644 app/src/main/res/mipmap-xxhdpi/select_img.png create mode 100644 app/src/main/res/mipmap-xxhdpi/sese.png create mode 100644 app/src/main/res/mipmap-xxhdpi/sfz_add_img.png create mode 100644 app/src/main/res/mipmap-xxhdpi/sfzbm.png create mode 100644 app/src/main/res/mipmap-xxhdpi/sfzzm.png create mode 100644 app/src/main/res/mipmap-xxhdpi/top_bg.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/new_bg_index.png create mode 100644 app/src/main/res/values-night/colors.xml create mode 100644 app/src/main/res/values-night/themes.xml create mode 100644 app/src/main/res/values-zh/values-zh.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/font_certs.xml create mode 100644 app/src/main/res/values/ids.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/themes.xml create mode 100644 app/src/main/res/xml/file_paths.xml create mode 100644 app/src/main/res/xml/file_paths_csj.xml create mode 100644 app/src/main/res/xml/gdt_file_path.xml create mode 100644 app/src/main/res/xml/network_security_config.xml create mode 100644 app/src/test/java/com/bikao/cleanmark/ExampleUnitTest.java create mode 100644 app/videomark.jks create mode 100644 basicLib/.gitignore create mode 100644 basicLib/build.gradle create mode 100644 basicLib/proguard-rules.pro create mode 100644 basicLib/src/main/AndroidManifest.xml create mode 100644 basicLib/src/main/java/com/azhon/basic/adapter/BaseDBRVAdapter.java create mode 100644 basicLib/src/main/java/com/azhon/basic/adapter/BaseDBRVHolder.java create mode 100644 basicLib/src/main/java/com/azhon/basic/adapter/OnItemClickListener.java create mode 100644 basicLib/src/main/java/com/azhon/basic/base/BaseActivity.java create mode 100644 basicLib/src/main/java/com/azhon/basic/base/BaseFragment.java create mode 100644 basicLib/src/main/java/com/azhon/basic/base/BaseLazyFragment.java create mode 100644 basicLib/src/main/java/com/azhon/basic/base/BaseNoModelActivity.java create mode 100644 basicLib/src/main/java/com/azhon/basic/base/BaseNoModelFragment.java create mode 100644 basicLib/src/main/java/com/azhon/basic/bean/DialogBean.java create mode 100644 basicLib/src/main/java/com/azhon/basic/lifecycle/BaseViewModel.java create mode 100644 basicLib/src/main/java/com/azhon/basic/lifecycle/DialogLiveData.java create mode 100644 basicLib/src/main/java/com/azhon/basic/retrofit/BaseApi.java create mode 100644 basicLib/src/main/java/com/azhon/basic/utils/ActivityUtil.java create mode 100644 basicLib/src/main/java/com/azhon/basic/utils/AnimUtil.java create mode 100644 basicLib/src/main/java/com/azhon/basic/utils/ApkUtil.java create mode 100644 basicLib/src/main/java/com/azhon/basic/utils/DensityUtil.java create mode 100644 basicLib/src/main/java/com/azhon/basic/utils/SharePreUtil.java create mode 100644 basicLib/src/main/java/com/azhon/basic/utils/SnackbarUtils.java create mode 100644 basicLib/src/main/java/com/azhon/basic/utils/TimeUtil.java create mode 100644 basicLib/src/main/java/com/azhon/basic/view/LoadingDialog.java create mode 100644 basicLib/src/main/res/drawable/dialog_loading_bg.xml create mode 100644 basicLib/src/main/res/layout/dialog_loading.xml create mode 100644 basicLib/src/main/res/values/strings.xml create mode 100644 basicLib/src/main/res/values/styles.xml create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 matisse/.gitignore create mode 100644 matisse/build.gradle create mode 100644 matisse/gradle.properties create mode 100644 matisse/proguard-rules.pro create mode 100644 matisse/src/main/AndroidManifest.xml create mode 100644 matisse/src/main/java/com/zhihu/matisse/Matisse.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/MimeType.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/SelectionCreator.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/engine/ImageEngine.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/engine/impl/GlideEngine.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/engine/impl/PicassoEngine.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/filter/Filter.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/entity/Album.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/entity/CaptureStrategy.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/entity/IncapableCause.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/entity/Item.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/entity/SelectionSpec.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/loader/AlbumLoader.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/loader/AlbumMediaLoader.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/model/AlbumCollection.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/model/AlbumMediaCollection.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/model/SelectedItemCollection.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/AlbumPreviewActivity.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/BasePreviewActivity.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/MediaSelectionFragment.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/PreviewItemFragment.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/SelectedPreviewActivity.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/adapter/AlbumMediaAdapter.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/adapter/AlbumsAdapter.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/adapter/PreviewPagerAdapter.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/adapter/RecyclerViewCursorAdapter.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/widget/AlbumsSpinner.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/widget/CheckRadioView.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/widget/CheckView.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/widget/IncapableDialog.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/widget/MediaGrid.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/widget/MediaGridInset.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/widget/PreviewViewPager.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/widget/RoundedRectangleImageView.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/ui/widget/SquareFrameLayout.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/utils/ExifInterfaceCompat.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/utils/MediaStoreCompat.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/utils/PathUtils.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/utils/PhotoMetadataUtils.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/utils/Platform.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/utils/SingleMediaScanner.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/internal/utils/UIUtils.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/listener/OnCheckedListener.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/listener/OnFragmentInteractionListener.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/listener/OnSelectedListener.java create mode 100644 matisse/src/main/java/com/zhihu/matisse/ui/MatisseActivity.java create mode 100644 matisse/src/main/res/color/dracula_bottom_toolbar_apply.xml create mode 100644 matisse/src/main/res/color/dracula_bottom_toolbar_preview.xml create mode 100644 matisse/src/main/res/color/dracula_preview_bottom_toolbar_apply.xml create mode 100644 matisse/src/main/res/color/zhihu_bottom_toolbar_apply.xml create mode 100644 matisse/src/main/res/color/zhihu_bottom_toolbar_preview.xml create mode 100644 matisse/src/main/res/color/zhihu_preview_bottom_toolbar_apply.xml create mode 100644 matisse/src/main/res/drawable-hdpi/ic_arrow_drop_down_white_24dp.png create mode 100644 matisse/src/main/res/drawable-hdpi/ic_check_white_18dp.png create mode 100644 matisse/src/main/res/drawable-hdpi/ic_empty_dracula.png create mode 100644 matisse/src/main/res/drawable-hdpi/ic_empty_zhihu.png create mode 100644 matisse/src/main/res/drawable-hdpi/ic_gif.png create mode 100644 matisse/src/main/res/drawable-hdpi/ic_play_circle_outline_white_48dp.png create mode 100644 matisse/src/main/res/drawable-hdpi/ic_preview_radio_off.webp create mode 100644 matisse/src/main/res/drawable-hdpi/ic_preview_radio_on.webp create mode 100644 matisse/src/main/res/drawable-mdpi/ic_arrow_drop_down_white_24dp.png create mode 100644 matisse/src/main/res/drawable-mdpi/ic_check_white_18dp.png create mode 100644 matisse/src/main/res/drawable-mdpi/ic_empty_dracula.png create mode 100644 matisse/src/main/res/drawable-mdpi/ic_empty_zhihu.png create mode 100644 matisse/src/main/res/drawable-mdpi/ic_gif.png create mode 100644 matisse/src/main/res/drawable-mdpi/ic_play_circle_outline_white_48dp.png create mode 100644 matisse/src/main/res/drawable-mdpi/ic_preview_radio_off.webp create mode 100644 matisse/src/main/res/drawable-mdpi/ic_preview_radio_on.webp create mode 100644 matisse/src/main/res/drawable-xhdpi/ic_arrow_drop_down_white_24dp.png create mode 100644 matisse/src/main/res/drawable-xhdpi/ic_check_white_18dp.png create mode 100644 matisse/src/main/res/drawable-xhdpi/ic_empty_dracula.png create mode 100644 matisse/src/main/res/drawable-xhdpi/ic_empty_zhihu.png create mode 100644 matisse/src/main/res/drawable-xhdpi/ic_gif.png create mode 100644 matisse/src/main/res/drawable-xhdpi/ic_play_circle_outline_white_48dp.png create mode 100644 matisse/src/main/res/drawable-xhdpi/ic_preview_radio_off.webp create mode 100644 matisse/src/main/res/drawable-xhdpi/ic_preview_radio_on.webp create mode 100644 matisse/src/main/res/drawable-xxhdpi/ic_arrow_drop_down_white_24dp.png create mode 100644 matisse/src/main/res/drawable-xxhdpi/ic_black_back.png create mode 100644 matisse/src/main/res/drawable-xxhdpi/ic_check_white_18dp.png create mode 100644 matisse/src/main/res/drawable-xxhdpi/ic_empty_dracula.png create mode 100644 matisse/src/main/res/drawable-xxhdpi/ic_empty_zhihu.png create mode 100644 matisse/src/main/res/drawable-xxhdpi/ic_gif.png create mode 100644 matisse/src/main/res/drawable-xxhdpi/ic_play_circle_outline_white_48dp.png create mode 100644 matisse/src/main/res/drawable-xxxhdpi/ic_arrow_drop_down_white_24dp.png create mode 100644 matisse/src/main/res/drawable-xxxhdpi/ic_check_white_18dp.png create mode 100644 matisse/src/main/res/drawable-xxxhdpi/ic_empty_dracula.png create mode 100644 matisse/src/main/res/drawable-xxxhdpi/ic_empty_zhihu.png create mode 100644 matisse/src/main/res/drawable-xxxhdpi/ic_gif.png create mode 100644 matisse/src/main/res/drawable-xxxhdpi/ic_photo_camera_white_24dp.png create mode 100644 matisse/src/main/res/drawable-xxxhdpi/ic_play_circle_outline_white_48dp.png create mode 100644 matisse/src/main/res/layout/activity_matisse.xml create mode 100644 matisse/src/main/res/layout/activity_media_preview.xml create mode 100644 matisse/src/main/res/layout/album_list_item.xml create mode 100644 matisse/src/main/res/layout/fragment_media_selection.xml create mode 100644 matisse/src/main/res/layout/fragment_preview_item.xml create mode 100644 matisse/src/main/res/layout/media_grid_content.xml create mode 100644 matisse/src/main/res/layout/media_grid_item.xml create mode 100644 matisse/src/main/res/layout/photo_capture_item.xml create mode 100644 matisse/src/main/res/values-zh-rTW/strings.xml create mode 100644 matisse/src/main/res/values-zh/strings.xml create mode 100644 matisse/src/main/res/values/attrs.xml create mode 100644 matisse/src/main/res/values/colors.xml create mode 100644 matisse/src/main/res/values/colors_dracula.xml create mode 100644 matisse/src/main/res/values/colors_zhihu.xml create mode 100644 matisse/src/main/res/values/dimens.xml create mode 100644 matisse/src/main/res/values/strings.xml create mode 100644 matisse/src/main/res/values/styles.xml create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d4c3a57 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties +/.idea/ diff --git a/README.md b/README.md index d956c49..80ec208 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,9 @@ -# trustlend +# 红色的贷款项目 -## Getting started +## 架构采用MVVM结构 -To make it easy for you to get started with GitLab, here's a list of recommended next steps. -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! -## Add your files -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: - -``` -cd existing_repo -git remote add origin http://git.dengshikj.com/xuhuixiang/trustlend.git -git branch -M master -git push -uf origin master -``` - -## Integrate with your tools - -- [ ] [Set up project integrations](http://git.dengshikj.com/xuhuixiang/trustlend/-/settings/integrations) - -## Collaborate with your team - -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README - -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/.idea/.gitignore b/app/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/app/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/app/.idea/gradle.xml b/app/.idea/gradle.xml new file mode 100644 index 0000000..b898c0a --- /dev/null +++ b/app/.idea/gradle.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.idea/misc.xml b/app/.idea/misc.xml new file mode 100644 index 0000000..46fefaa --- /dev/null +++ b/app/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/.idea/modules.xml b/app/.idea/modules.xml new file mode 100644 index 0000000..84d987c --- /dev/null +++ b/app/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/app/.idea/vcs.xml b/app/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/app/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..4b832d7 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,112 @@ +plugins { + id 'com.android.application' + id 'kotlin-android' +} + +android { + compileSdkVersion 30 + + defaultConfig { + applicationId "com.dskj.daikuan" + minSdkVersion 23 + targetSdkVersion 30 + versionCode 110 + versionName "1.1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" +// configurations.all { +// resolutionStrategy { force 'androidx.core:core-ktx:1.6.0' } +// } + ndk { + abiFilters "arm64-v8a"//,"armeabi-v7a", "x86", "x86_64" + } + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + debug { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + useLibrary 'org.apache.http.legacy' + //启用DataBinding + buildFeatures{ + dataBinding = true + // for view binding : + // viewBinding = true + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + + signingConfigs { + debug { + storeFile file('videomark.jks') + storePassword "123456" + keyAlias 'videomark' + keyPassword "123456" + } + release { + storeFile file('videomark.jks') + storePassword "123456" + keyAlias 'videomark' + keyPassword "123456" + } + } + lintOptions { + checkReleaseBuilds false + abortOnError false + } +} + +configurations.all{ + resolutionStrategy{ + force 'androidx.core:core:1.6.0' + } +} + +dependencies { + implementation 'com.github.tbruyelle:rxpermissions:0.10.2' + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.3.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + testImplementation "junit:junit:4.13.1" + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + //viewmode需要引入的依赖 livedate 之类的就依赖他了 + implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' + + implementation project(path: ':basicLib') + implementation "androidx.fragment:fragment-ktx:1.4.0" + implementation "androidx.core:core-ktx:1.3.2" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'io.reactivex:rxjava:1.3.0' + implementation 'io.reactivex:rxandroid:1.2.1' + // okhttp 3 + implementation 'com.squareup.okhttp3:okhttp:3.10.0' + implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0' + + implementation 'com.github.Hitomis:transferee:1.6.1' + // 添加 Glide 图片加载器 + implementation 'com.github.Hitomis.transferee:GlideImageLoader:1.6.1' + implementation 'com.gyf.immersionbar:immersionbar:2.3.3' + + implementation project(path: ':matisse') + + + //以下3个 下拉刷新和加载更多依赖 + implementation 'com.scwang.smart:refresh-layout-kernel:2.0.1' + //核心必须依赖 + implementation 'com.scwang.smart:refresh-header-classics:2.0.1' + //经典刷新头 + implementation 'com.scwang.smart:refresh-footer-classics:2.0.1' + implementation 'com.scwang.smart:refresh-footer-ball:2.0.1' + +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..6d5f060 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,451 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile +-keepclassmembers class fqcn.of.javascript.interface.for.webview { + public *; +} +#指定代码的压缩级别 +-optimizationpasses 5 + +#包明不混合大小写 +-dontusemixedcaseclassnames + +#不去忽略非公共的库类 +-dontskipnonpubliclibraryclasses + + #优化 不优化输入的类文件 +-dontoptimize + + #预校验 +-dontpreverify + + #混淆时是否记录日志 +-verbose + + # 混淆时所采用的算法 +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +#忽略警告 +-ignorewarning + + +-keep public class * extends android.app.Fragment +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference + +-keep class com.bikao.cleanmark.view.** { *; } +-keep class com.coremedia.iso.** {*;} +-keep class nu.xom.** {*;} +-keep class com.googlecode.mp4parser.** {*;} +-keep class com.mp4parser.** {*;} +-keep class com.coremedia.iso.** {*;} +-keep class org.aspectj.** {*;} + +-keep class jp.co.recruit_lifestyle.android.floatingview.** {*;} + +# 如果有引用v4包可以添加下面这行 +-keep class android.support.v4.**{ *;} + +# 如果引用了v4或者v7包 +-dontwarn android.support.** + +# 保持 native 方法不被混淆 +-keepclasseswithmembernames class * { + native ; +} + +-keep class com.bikao.dkplayer.** {*;} + +# 保护注解 +-keepattributes *Annotation* +-keep class * extends java.lang.annotation.Annotation {*;} + +# 泛型与反射 +-keepattributes Signature +-keepattributes EnclosingMethod + +# 不混淆内部类 +-keepattributes InnerClasses + +# gson +-dontwarn com.google.** +-keep class com.google.gson.** {*;} + + +#保持枚举 enum 类不被混淆 +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +# otto混淆规则 +-keepattributes *Annotation* +-keepclassmembers class ** { + @com.squareup.otto.Subscribe public *; + @com.squareup.otto.Produce public *; +} +#所有bean都不要混淆 +-keep class * implements java.io.Serializable {*;} +-keepclassmembers class * implements java.io.Serializable {*;} +-keep class * implements java.lang.Comparable {*;} +-keepclassmembers class * implements java.lang.Comparable {*;} +-keep class com.bikao.cleanmark.bean.** { *; } + +#一般网络层都不进行混淆 +-keep class com.xxx.xxx.http.** {*;} + +#如果你遇到一些控件无法Inflate,报NullPointException,比如ListView,NavigationView等等 +#-keep class org.xmlpull.v1.** {*;} + +# OkHttp +-dontwarn com.squareup.okhttp.** +-keep class com.squareup.okhttp.** {*;} +-keep interface com.squareup.okhttp.** {*;} +-dontwarn okio.** + +# Realm +-keep class io.realm.annotations.RealmModule +-keep @io.realm.annotations.RealmModule class * +-keep class io.realm.internal.Keep +-keep @io.realm.internal.Keep class * { *; } +-dontwarn javax.** +-dontwarn io.realm.** + +#友盟 +-keep class com.umeng.** {*;} + +-keep class com.uc.** {*;} + +-keepclassmembers class * { + public (org.json.JSONObject); +} +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} +-keep class com.zui.** {*;} +-keep class com.miui.** {*;} +-keep class com.heytap.** {*;} +-keep class a.** {*;} +-keep class com.vivo.** {*;} + +-keep public class com.adwl.location.R$*{ +public static final int *; +} + +#lambda +-dontwarn java.lang.invoke.* +-dontwarn **$$Lambda$* + +#基线包使用,生成mapping.txt +-printmapping mapping.txt +#生成的mapping.txt在app/buidl/outputs/mapping/release路径下,移动到/app路径下 + +#修复后的项目使用,保证混淆结果一致 +#-applymapping mapping.txt + +#Glide +-keep public class * implements com.bumptech.glide.module.GlideModule +-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { + **[] $VALUES; + public *; +} + +-keep class com.bytedance.sdk.openadsdk.** { *; } +-keep public interface com.bytedance.sdk.openadsdk.downloadnew.** {*;} +-keep class com.pgl.sys.ces.* {*;} + +# for DexGuard only +#-keepresourcexmlelements manifest/application/meta-data@value=GlideModule + +#butterknife + -dontwarn butterknife.internal.** +# -keep class butterknife.** { *; } +# -dontwarn butterknife.internal.** +# -keep class **$$ViewBinder { *; } +# -keepclasseswithmembernames class * { @butterknife.* ;} +# -keepclasseswithmembernames class * { @butterknife.* ;} + +#SweetAlert +-keep class cn.pedant.SweetAlert.**{*;} +-keep class cn.pedant.SweetAlert.Rotate3dAnimation { + public (...); +} + +#retrofit2 +# Platform calls Class.forName on typeswhich do not exist on Android to determine platform. +-dontnote retrofit2.Platform + +# Platform used when running on RoboVM oniOS. Will not be used at runtime. +-dontnote retrofit2.Platform$IOS$MainThreadExecutor + +# Platform used when running on Java 8 VMs.Will not be used at runtime. +-dontwarn retrofit2.Platform$Java8 + +# Retain generic type information for useby reflection by converters and adapters. +-keepattributes Signature + +# Retain declared checked exceptions foruse by a Proxy instance. +-keepattributes Exceptions + +# Retrofit +-dontwarn retrofit2.** +-keep class retrofit2.** { *; } + +# Retrolambda +-dontwarn java.lang.invoke.* + + +# RxJava RxAndroid +-dontwarn sun.misc.** +-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { + long producerIndex; + long consumerIndex; +} +-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { + rx.internal.util.atomic.LinkedQueueNode producerNode; +} +-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { + rx.internal.util.atomic.LinkedQueueNode consumerNode; +} + +# EventBus混淆 +-keepclassmembers class ** { + public void onEvent*(***); +} +# Only required if you use AsyncExecutor +-keepclassmembers class * extends de.greenrobot.event.util.ThrowableFailureEvent { + public (java.lang.Throwable); +} +# Don't warn for missing support classes +-dontwarn de.greenrobot.event.util.*$Support +-dontwarn de.greenrobot.event.util.*$SupportManagerFragment + +-keep class com.gyf.immersionbar.* {*;} + -dontwarn com.gyf.immersionbar.** + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep public class com.bikao.cleanmark.R$*{ +public static final int *; +} + +#ijk +#ijkplayer +-keep class tv.danmaku.ijk.media.player.** {*;} +-keep class tv.danmaku.ijk.media.player.IjkMediaPlayer{*;} +-keep class tv.danmaku.ijk.media.player.ffmpeg.FFmpegApi{*;} + +# //smack + -keep class org.jxmpp.** {*;} + -keep class de.measite.** {*;} + -keep class org.jivesoftware.** {*;} + -keep class org.xmlpull.** {*;} + -dontwarn org.xbill.** + -keep class org.xbill.** {*;} + +# //eventbus + -keepattributes *Annotation* + -keepclassmembers class ** { + @org.greenrobot.eventbus.Subscribe ; + } + -keep enum org.greenrobot.eventbus.ThreadMode { *; } + + # Only required if you use AsyncExecutor + -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { + (java.lang.Throwable); + } + + -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip + -keep @com.facebook.common.internal.DoNotStrip class * + -keepclassmembers class * { + @com.facebook.common.internal.DoNotStrip *; + } + # Keep native methods + -keepclassmembers class * { + native ; + } + + -dontwarn okio.** + -dontwarn com.squareup.okhttp.** + -dontwarn okhttp3.** + -dontwarn javax.annotation.** + -dontwarn com.android.volley.toolbox.** + -dontwarn com.facebook.infer.** + + + + -keep class com.iflytek.**{*;} + +#UShare +-dontshrink +-dontoptimize +-dontwarn com.google.android.maps.** +-dontwarn android.webkit.WebView +-dontwarn com.umeng.** +-dontwarn com.tencent.weibo.sdk.** +-dontwarn com.facebook.** +-keep public class javax.** +-keep public class android.webkit.** +-dontwarn android.support.v4.** +-keep enum com.facebook.** +-keepattributes Exceptions,InnerClasses,Signature +-keepattributes *Annotation* +-keepattributes SourceFile,LineNumberTable +-keep public interface com.facebook.** +-keep public interface com.tencent.** +-keep public interface com.umeng.socialize.** +-keep public interface com.umeng.socialize.sensor.** +-keep public interface com.umeng.scrshot.** +-keep public class com.umeng.socialize.* {*;} +-keep class com.facebook.** +-keep class com.facebook.** { *; } +-keep class com.umeng.scrshot.** +-keep public class com.tencent.** {*;} +-keep class com.umeng.socialize.sensor.** +-keep class com.umeng.socialize.handler.** +-keep class com.umeng.socialize.handler.* +-keep class com.umeng.weixin.handler.** +-keep class com.umeng.weixin.handler.* +-keep class com.umeng.qq.handler.** +-keep class com.umeng.qq.handler.* +-keep class UMMoreHandler{*;} +-keep class com.tencent.mm.sdk.modelmsg.WXMediaMessage {*;} +-keep class com.tencent.mm.sdk.modelmsg.** implements com.tencent.mm.sdk.modelmsg.WXMediaMessage$IMediaObject {*;} +-keep class im.yixin.sdk.api.YXMessage {*;} +-keep class im.yixin.sdk.api.** implements im.yixin.sdk.api.YXMessage$YXMessageData{*;} +-keep class com.tencent.mm.sdk.** { + *; +} +-keep class com.tencent.mm.opensdk.** { + *; +} +-keep class com.tencent.wxop.** { + *; +} +-keep class com.tencent.mm.sdk.** { + *; +} +-keep class com.umeng.** {*;} +-dontwarn twitter4j.** +-keep class twitter4j.** { *; } +-keep class com.tencent.** {*;} +-dontwarn com.tencent.** +-keep class com.kakao.** {*;} +-dontwarn com.kakao.** +-keep public class com.umeng.com.umeng.soexample.R$*{ + public static final int *; +} +-keep public class com.linkedin.android.mobilesdk.R$*{ + public static final int *; +} +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} +-keep class com.tencent.open.TDialog$* +-keep class com.tencent.open.TDialog$* {*;} +-keep class com.tencent.open.PKDialog +-keep class com.tencent.open.PKDialog {*;} +-keep class com.tencent.open.PKDialog$* +-keep class com.tencent.open.PKDialog$* {*;} +-keep class com.umeng.socialize.impl.ImageImpl {*;} +-keep class com.sina.** {*;} +-dontwarn com.sina.** +-keep class com.alipay.share.sdk.** { + *; +} +-keep class * implements android.os.Parcelable {*;} + +-keepnames class * implements android.os.Parcelable { + public static final ** CREATOR; +} +-keepclassmembers class * implements android.os.Parcelable {*;} + +-keep class com.linkedin.** { *; } +-keep class com.android.dingtalk.share.ddsharemodule.** { *; } +-keepattributes Signature +#UShare + + +# 请开发者根据自己实际情况给第三方库的添加相应的混淆设置 +-dontwarn com.androidquery.** +-keep class com.androidquery.** { *;} + +-dontwarn tv.danmaku.** +-keep class tv.danmaku.** { *;} + +-dontwarn androidx.** + +# 如果使用了tbs版本的sdk需要进行以下配置 +-keep class com.tencent.smtt.** { *; } +-dontwarn dalvik.** +-dontwarn com.tencent.smtt.** + +-keep class com.google.android.exoplayer2.** { *; } +-dontwarn com.google.android.exoplayer2.** + +-keep class com.aplayer.** { *; } +-dontwarn com.aplayer.** + +-dontwarn com.tencent.bugly.** +-keep public class com.tencent.bugly.**{*;} + + +-keep class com.lljjcoder.**{ + *; +} + +-dontwarn demo.** +-keep class demo.**{*;} +-dontwarn net.sourceforge.pinyin4j.** +-keep class net.sourceforge.pinyin4j.**{*;} +-keep class net.sourceforge.pinyin4j.format.**{*;} +-keep class net.sourceforge.pinyin4j.format.exception.**{*;} + +-keepattributes *Annotation* +-keepattributes Exceptions +-keepattributes InnerClasses +-keepattributes Signature +-keepattributes SourceFile,LineNumberTable + +-keep class com.bytedance.sdk.openadsdk.** { *; } +-keep class com.bytedance.frameworks.** { *; } + +-keep class ms.bd.c.Pgl.**{*;} +-keep class com.bytedance.mobsec.metasec.ml.**{*;} + +-keep class com.ss.android.**{*;} + +-keep class com.bytedance.embedapplog.** {*;} +-keep class com.bytedance.embed_dr.** {*;} + +-keep class com.bykv.vk.** {*;} + +-ignorewarnings \ No newline at end of file diff --git a/app/src/androidTest/java/com/bikao/cleanmark/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/bikao/cleanmark/ExampleInstrumentedTest.java new file mode 100644 index 0000000..b1c499b --- /dev/null +++ b/app/src/androidTest/java/com/bikao/cleanmark/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.bikao.cleanmark; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.bikao.watermark", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..d3df733 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/dskj/daikuan/InitApp.java b/app/src/main/java/com/dskj/daikuan/InitApp.java new file mode 100644 index 0000000..0f36d20 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/InitApp.java @@ -0,0 +1,156 @@ +package com.dskj.daikuan; + +import android.app.Activity; +import android.app.Application; +import android.content.Context; +import android.content.SharedPreferences; +import android.text.TextUtils; + +import com.dskj.daikuan.bean.UserBean; +import com.dskj.daikuan.config.Config; +import com.dskj.daikuan.utils.DeviceUtil; +import com.dskj.daikuan.utils.GsonUtils; + + + +/** + * Application 主入口 + * + * @author xuhuixiang + */ + +public class InitApp extends Application { + public static Context AppContext; + public static InitApp initApp; + + public static Context getAppContext() { + return AppContext; + } + + + @Override + protected void attachBaseContext(Context base) { + super.attachBaseContext(base); + + } + + + + @Override + public void onCreate() { + super.onCreate(); + AppContext = getApplicationContext(); + initApp = this; + DeviceUtil.init(this); + initARouter(); + + + } + + + private void initARouter() { + + } + + //----------------------------SharedPreferences的全局存储实现 人懒 懒得抽文件--------------------------------------- + + public static void saveInt(String key, int value) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putInt(key, value); + editor.apply(); + } + + public static void saveFloat(String key, float value) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putFloat(key, value); + editor.apply(); + } + + public static void saveLong(String key, long value) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putLong(key, value); + editor.apply(); + } + + public static void saveString(String key, String value) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putString(key, value); + editor.apply(); + } + + public static void deleteKey(String key) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + if (!sp.contains(key)) return; + SharedPreferences.Editor editor = sp.edit(); + editor.remove(key); + editor.apply(); + } + + public static void saveBoolean(String key, boolean value) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putBoolean(key, value); + editor.apply(); + } + + public static int getInt(String key, int defValue) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getInt(key, defValue); + } + + public static float getFloat(String key, float defValue) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getFloat(key, defValue); + } + + public static long getLong(String key, long defValue) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getLong(key, defValue); + } + + public static boolean getBoolean(String key, boolean defValue) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getBoolean(key, defValue); + } + + public static String getString(String key, String defValue) { + Context context = AppContext; + if (context == null) { + return defValue; + } + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getString(key, defValue); + } + + public static UserBean getUserBean() { + Context context = AppContext; + if (context == null) { + return null; + } + String name = getString("user_bean",""); + if(TextUtils.isEmpty(name)){ + return null; + } + return GsonUtils.getObjFromJSON(name,UserBean.class); + } + + public static String getToken() { + Context context = AppContext; + if (context == null) { + return ""; + } + return ""; + } + + public static void setToken(String value) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putString(Config.API_TOKEN_TAG, value); + editor.apply(); + } + +} diff --git a/app/src/main/java/com/dskj/daikuan/adapter/BaseAdapter.java b/app/src/main/java/com/dskj/daikuan/adapter/BaseAdapter.java new file mode 100644 index 0000000..9a7a414 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/adapter/BaseAdapter.java @@ -0,0 +1,68 @@ +package com.dskj.daikuan.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.recyclerview.widget.RecyclerView; + +public abstract class BaseAdapter extends RecyclerView.Adapter implements View.OnClickListener, View.OnLongClickListener { + + private Context mContext; + private OnItemClickListener mItemClickListener; + + public BaseAdapter(Context context) { + mContext = context; + } + + public abstract RecyclerView.ViewHolder getViewHolder(View itemView); + + public abstract int getItemViewResource(); + + public abstract void bindItemData(RecyclerView.ViewHolder holder, int position); + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + int resource = getItemViewResource(); + if (resource <= 0) return null; + + View view = LayoutInflater.from(mContext).inflate(resource, parent, false); + view.setOnClickListener(this); + view.setOnLongClickListener(this); + return getViewHolder(view); + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + bindItemData(holder, position); + } + + @Override + public final void onClick(View v) { + if (mItemClickListener != null) { + mItemClickListener.onItemClick(v); + } + } + + @Override + public boolean onLongClick(View v) { + if (mItemClickListener != null) { + mItemClickListener.onItemLongClick(v); + } + return false; + } + + public Context getContext() { + return mContext; + } + + public void setItemClickListener(OnItemClickListener itemClickListener) { + mItemClickListener = itemClickListener; + } + + public interface OnItemClickListener { + void onItemClick(View v); + void onItemLongClick(View v); + } +} diff --git a/app/src/main/java/com/dskj/daikuan/adapter/CommunityAdapter.java b/app/src/main/java/com/dskj/daikuan/adapter/CommunityAdapter.java new file mode 100644 index 0000000..a0e9558 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/adapter/CommunityAdapter.java @@ -0,0 +1,34 @@ +package com.dskj.daikuan.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.viewpager2.adapter.FragmentStateAdapter; + +import java.util.ArrayList; +import java.util.List; + +public class CommunityAdapter extends FragmentStateAdapter { + private ArrayList listTitle; + private List listFragment; + + + public CommunityAdapter(@NonNull FragmentActivity fragmentActivity, ArrayList listTitle, List listFragment) { + super(fragmentActivity); + this.listTitle = listTitle; + this.listFragment = listFragment; + } + + + @NonNull + @Override + public Fragment createFragment(int position) { + return listFragment.get(position); + } + + @Override + public int getItemCount() { + return listFragment.size(); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/dskj/daikuan/adapter/GoodsAdapter.java b/app/src/main/java/com/dskj/daikuan/adapter/GoodsAdapter.java new file mode 100644 index 0000000..1d1029b --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/adapter/GoodsAdapter.java @@ -0,0 +1,34 @@ +package com.dskj.daikuan.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.viewpager2.adapter.FragmentStateAdapter; + +import java.util.ArrayList; +import java.util.List; + +public class GoodsAdapter extends FragmentStateAdapter { + private ArrayList listTitle; + private List listFragment; + + + public GoodsAdapter(@NonNull FragmentActivity fragmentActivity, ArrayList listTitle, List listFragment) { + super(fragmentActivity); + this.listTitle = listTitle; + this.listFragment = listFragment; + } + + + @NonNull + @Override + public Fragment createFragment(int position) { + return listFragment.get(position); + } + + @Override + public int getItemCount() { + return listFragment.size(); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/dskj/daikuan/adapter/comm/CommonAdapter.java b/app/src/main/java/com/dskj/daikuan/adapter/comm/CommonAdapter.java new file mode 100644 index 0000000..26f3f15 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/adapter/comm/CommonAdapter.java @@ -0,0 +1,70 @@ +package com.dskj.daikuan.adapter.comm; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + +/** + * 通用列表适配器 + * @param + */ +public abstract class CommonAdapter extends RecyclerView.Adapter { + + protected Context mContext; + protected int mLayoutId; + protected List mDatas; + protected LayoutInflater mInflater; + + ViewHolder viewHolder; + + + public CommonAdapter(Context context, int layoutId, List datas) { + mContext = context; + mInflater = LayoutInflater.from(context); + mLayoutId = layoutId; + mDatas = datas; + } + public void setDates(List dates){ + this.mDatas=dates; +// notifyItemRangeChanged(0,mDatas.size()); + notifyDataSetChanged(); + } + public void addDates(List dates){ + this.mDatas.addAll(dates); + notifyDataSetChanged(); + } + + public void addDates(int localSize){ + int size=mDatas.size(); + notifyItemRangeChanged(size,localSize); + } + public List getDates(){ + return this.mDatas; + } + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + viewHolder = ViewHolder.get(mContext, parent, mLayoutId); + return viewHolder; + } + + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + + convert(holder, mDatas.get(position),position); + } + + public abstract void convert(ViewHolder holder, T t,int index); + + + @Override + public int getItemCount() { + return mDatas.size(); + } +} diff --git a/app/src/main/java/com/dskj/daikuan/adapter/comm/ViewHolder.java b/app/src/main/java/com/dskj/daikuan/adapter/comm/ViewHolder.java new file mode 100644 index 0000000..ec080d5 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/adapter/comm/ViewHolder.java @@ -0,0 +1,60 @@ +package com.dskj.daikuan.adapter.comm; + +import android.content.Context; +import android.util.SparseArray; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.recyclerview.widget.RecyclerView; + +/** + * 通用列表ViewHolder + */ +public class ViewHolder extends RecyclerView.ViewHolder { + + private SparseArray mViews; + private View mConvertView; + private Context mContext; + + public ViewHolder(Context context, View itemView, ViewGroup parent) { + super(itemView); + mContext = context; + mConvertView = itemView; + mViews = new SparseArray(); + } + + public static ViewHolder get(Context context, ViewGroup parent, int layoutId) { + + View itemView = LayoutInflater.from(context).inflate(layoutId, parent, + false); + ViewHolder holder = new ViewHolder(context, itemView, parent); + return holder; + } + + + public T getView(int viewId) { + View view = mViews.get(viewId); + if (view == null) { + view = mConvertView.findViewById(viewId); + mViews.put(viewId, view); + } + return (T) view; + } + + + public ViewHolder setText(int viewId, String text) + { + TextView tv = getView(viewId); + tv.setText(text); + return this; + } + + public ViewHolder setOnClickListener(int viewId, View.OnClickListener listener) { + View view = getView(viewId); + view.setOnClickListener(listener); + return this; + } + +} diff --git a/app/src/main/java/com/dskj/daikuan/api/Api.java b/app/src/main/java/com/dskj/daikuan/api/Api.java new file mode 100644 index 0000000..f9d30ef --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/api/Api.java @@ -0,0 +1,76 @@ +package com.dskj.daikuan.api; + +import android.text.TextUtils; + +import com.azhon.basic.retrofit.BaseApi; +import com.dskj.daikuan.InitApp; +import com.dskj.daikuan.config.Config; +import com.dskj.daikuan.utils.LogUtils; + +import java.util.HashMap; +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; + +/** + * 项目名: TODO-MVVM + * 包名 com.azhon.mvvm.api + * 文件名: Api + * 创建时间: 2019-03-27 on 14:56 + * 描述: TODO 使用Retrofit基础服务 + * + */ + +public class Api extends BaseApi { + + private static final long CONNECT_TIMEOUT = 10; + private static final long READ_TIMEOUT = 10; + private static final long WRITE_TIMEOUT = 10; + + /** + * 静态内部类单例 + */ + private static class ApiHolder { + private static Api api = new Api(); + private final static ApiService apiService = api.initRetrofit(ApiService.URL) + .create(ApiService.class); + + } + + public static ApiService getInstance() { + return ApiHolder.apiService; + } + + + /** + * 做自己需要的操作 + */ + @Override + protected OkHttpClient setClient() { + OkHttpClient.Builder builder; + builder = new OkHttpClient() + .newBuilder(); + //禁止使用代理抓取数据 +// builder.proxy(Proxy.NO_PROXY); + //设置超时 + builder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS); + builder.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS); + builder.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS); + //错误重连 + builder.retryOnConnectionFailure(true); + builder.addInterceptor(new HeaderInterceptor()); + + if(Config.IS_DEBUG) { + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(message -> { + String text = message; + LogUtils.i("OKHttp111111-----", text); + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + builder.addInterceptor(interceptor); + } + return builder.build(); + + } + +} diff --git a/app/src/main/java/com/dskj/daikuan/api/ApiService.java b/app/src/main/java/com/dskj/daikuan/api/ApiService.java new file mode 100644 index 0000000..22cfdae --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/api/ApiService.java @@ -0,0 +1,42 @@ +package com.dskj.daikuan.api; + + +import com.dskj.daikuan.bean.VideoIndexResult; +import com.dskj.daikuan.bean.VideoResult; +import io.reactivex.Observable; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; + +/** + * 项目名: + * 包名 com.azhon.mvvm.api + * 文件名: ApiService + * 创建时间: 2019-03-27 on 14:55 + * 描述: + * + */ + +public interface ApiService { + +// String URL="https://www.csyltest.com/"; + String URL="https://8660ee.vip/"; + + @FormUrlEncoded + @POST("frontend/video/index") + Observable> videoIndex(@Field("token") String token); + + @FormUrlEncoded + @POST("frontend/video/list") + Observable> videoList(@Field("token") String token, @Field("id") String id, @Field("op") String op, + @Field("page") String page, @Field("nogame") String nogame); + + @FormUrlEncoded + @POST("https://www.csyltest.com/frontend/video/search") + Observable> search(@Field("token") String token,@Field("key") String key, + @Field("pagesize") String pagesize, @Field("page") String page, @Field("op") String op); + + @FormUrlEncoded + @POST("frontend/video/videoPlay") + Observable videoPlay(@Field("token") String token,@Field("id") String id); +} diff --git a/app/src/main/java/com/dskj/daikuan/api/BaseObserver.java b/app/src/main/java/com/dskj/daikuan/api/BaseObserver.java new file mode 100644 index 0000000..ee568ad --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/api/BaseObserver.java @@ -0,0 +1,114 @@ +package com.dskj.daikuan.api; + +import com.google.gson.JsonParseException; + +import org.json.JSONException; + +import java.io.InterruptedIOException; +import java.net.ConnectException; +import java.net.UnknownHostException; +import java.text.ParseException; + +import io.reactivex.observers.DisposableObserver; +import retrofit2.HttpException; + +public abstract class BaseObserver extends DisposableObserver { + /** + * 解析数据失败 + */ + public static final int PARSE_ERROR = 1001; + /** + * 网络问题 + */ + public static final int BAD_NETWORK = 1002; + /** + * 连接错误 + */ + public static final int CONNECT_ERROR = 1003; + /** + * 连接超时 + */ + public static final int CONNECT_TIMEOUT = 1004; + + @Override + public void onNext(T o) { + try { + Result model = (Result) o; +// LogUtils.i(GsonUtils.beanToJSONString(0)); + if (model.c == 200) { + onSuccess(o); + } else { + onError(model.c,model.m); + } + } catch (Exception e) { + e.printStackTrace(); + onError(407,e.toString()); + + } + + } + + @Override + public void onError(Throwable e) { + if (e instanceof HttpException) { + // HTTP错误 + onException(BAD_NETWORK); + } else if (e instanceof ConnectException + || e instanceof UnknownHostException) { + // 连接错误 + onException(CONNECT_ERROR); + } else if (e instanceof InterruptedIOException) { + // 连接超时 + onException(CONNECT_TIMEOUT); + } else if (e instanceof JsonParseException + || e instanceof JSONException + || e instanceof ParseException) { + // 解析错误 + + onException(PARSE_ERROR); + } else { +// if (e != null) { + onError(409,e.toString()); +// } else { +// onError(407, SophixStubApplication.instance().getString(R.string.unknown_error_txt)); +// } + } + + } + + private void onException(int unknownError) { +// switch (unknownError) { +// case CONNECT_ERROR: +// onError(CONNECT_ERROR,SophixStubApplication.instance().getString(R.string.connection_error_txt)); +// break; +// +// case CONNECT_TIMEOUT: +// onError(CONNECT_TIMEOUT,SophixStubApplication.instance().getString(R.string.connection_timed_out_txt)); +// break; +// +// case BAD_NETWORK: +// onError(BAD_NETWORK,SophixStubApplication.instance().getString(R.string.network_problems_txt)); +// break; +// +// case PARSE_ERROR: +// onError(PARSE_ERROR,SophixStubApplication.instance().getString(R.string.unknown_error_txt)); +// break; +// +// default: +// break; + +// } + onError(409,"未知错误"); + + } + + @Override + public void onComplete() { + + } + + public abstract void onSuccess(T o); + + public abstract void onError(int code,String msg); + +} diff --git a/app/src/main/java/com/dskj/daikuan/api/HeaderInterceptor.java b/app/src/main/java/com/dskj/daikuan/api/HeaderInterceptor.java new file mode 100644 index 0000000..3222919 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/api/HeaderInterceptor.java @@ -0,0 +1,28 @@ +package com.dskj.daikuan.api; + + +import com.dskj.daikuan.InitApp; +import com.dskj.daikuan.utils.LogUtils; + +import java.io.IOException; + +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; + +/** + * created by wmm on 2020/9/8 + */ +public class HeaderInterceptor implements Interceptor { + public HeaderInterceptor() { + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request request = chain.request().newBuilder() + .addHeader("authorization", InitApp.getToken()) + .build(); + LogUtils.i("头文件:"+InitApp.getToken()); + return chain.proceed(request); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/dskj/daikuan/api/Result.java b/app/src/main/java/com/dskj/daikuan/api/Result.java new file mode 100644 index 0000000..283055b --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/api/Result.java @@ -0,0 +1,30 @@ +package com.dskj.daikuan.api; + +import com.dskj.daikuan.utils.GsonUtils; + +import java.io.Serializable; + +/** + * created by wmm on 2020/9/8 + */ +public class Result implements Serializable { + + public String m; + public int c; + public T d; + public float comsume; + + + public boolean isSuccessful() { + return c == 200; + } + + @Override + public String toString() { + return "Result{" + + "message='" + m + '\'' + + ", code=" + c + + ", data=" + GsonUtils.beanToJSONString(d) + + '}'; + } +} diff --git a/app/src/main/java/com/dskj/daikuan/bean/ErrorMesage.java b/app/src/main/java/com/dskj/daikuan/bean/ErrorMesage.java new file mode 100644 index 0000000..5834a80 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/bean/ErrorMesage.java @@ -0,0 +1,31 @@ +package com.dskj.daikuan.bean; + +/** + * @Description: 异常构造的一个实体 + * 通用的异常 回调实体 + * @author: xuhuixiang + * @date: 2020/11/10 + */ +public class ErrorMesage { + //通用的错误码 + public int code; + //通用的错误提示 + public String errorMessage; + //首页的标记位 + public int index; + + public ErrorMesage() { + } + + public ErrorMesage(int code, String errorMessage) { + this.code = code; + this.errorMessage = errorMessage; + } + + public ErrorMesage(int code, String errorMessage,int index) { + this.code = code; + this.errorMessage = errorMessage; + this.index=index; + } + +} diff --git a/app/src/main/java/com/dskj/daikuan/bean/MemberOrder.java b/app/src/main/java/com/dskj/daikuan/bean/MemberOrder.java new file mode 100644 index 0000000..0bfc369 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/bean/MemberOrder.java @@ -0,0 +1,158 @@ +package com.dskj.daikuan.bean; + +import android.os.Parcel; +import android.os.Parcelable; + +public class MemberOrder implements Parcelable { + + /** + * id : 2 + * ordersn : lp163159813087508 + * uid : 4 + * type : 1 + * price : 2.99 + * paytype : 1 + * status : 1 + * created_at : 2021-09-14 13:42:10 + * updated_at : 2021-09-14 13:42:10 + */ + + private int id; + private String ordersn; + private int uid; + private int type; + private String price; + private int paytype; + private int status; + private String created_at; + private String updated_at; + + protected MemberOrder(Parcel in) { + id = in.readInt(); + ordersn = in.readString(); + uid = in.readInt(); + type = in.readInt(); + price = in.readString(); + paytype = in.readInt(); + status = in.readInt(); + created_at = in.readString(); + updated_at = in.readString(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(id); + dest.writeString(ordersn); + dest.writeInt(uid); + dest.writeInt(type); + dest.writeString(price); + dest.writeInt(paytype); + dest.writeInt(status); + dest.writeString(created_at); + dest.writeString(updated_at); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public MemberOrder createFromParcel(Parcel in) { + return new MemberOrder(in); + } + + @Override + public MemberOrder[] newArray(int size) { + return new MemberOrder[size]; + } + }; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getOrdersn() { + return ordersn; + } + + public void setOrdersn(String ordersn) { + this.ordersn = ordersn; + } + + public int getUid() { + return uid; + } + + public void setUid(int uid) { + this.uid = uid; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } + + public int getPaytype() { + return paytype; + } + + public void setPaytype(int paytype) { + this.paytype = paytype; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getCreated_at() { + return created_at; + } + + public void setCreated_at(String created_at) { + this.created_at = created_at; + } + + public String getUpdated_at() { + return updated_at; + } + + public void setUpdated_at(String updated_at) { + this.updated_at = updated_at; + } + + @Override + public String toString() { + return "MemberOrder{" + + "id=" + id + + ", ordersn='" + ordersn + '\'' + + ", uid=" + uid + + ", type=" + type + + ", price='" + price + '\'' + + ", paytype=" + paytype + + ", status=" + status + + ", created_at='" + created_at + '\'' + + ", updated_at='" + updated_at + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/dskj/daikuan/bean/UserBean.java b/app/src/main/java/com/dskj/daikuan/bean/UserBean.java new file mode 100644 index 0000000..86f2316 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/bean/UserBean.java @@ -0,0 +1,158 @@ +package com.dskj.daikuan.bean; + + +public class UserBean { + private int vip;//0 普通会员 1 会员 2 永久 + private String vip_expire; + private int id; + private String phone; + private String name; + private String comment; + private int praise; + private int gender; + private int reg_time; + private String avatar; + private int gold; + private String openid; + private int status; + private String token; + private int is_online; + private int last_time; + private int isNew; + + public String getVip_expire() { + return vip_expire; + } + + public void setVip_expire(String vip_expire) { + this.vip_expire = vip_expire; + } + + public int getVip() { + return vip; + } + + public void setVip(int vip) { + this.vip = vip; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public int getPraise() { + return praise; + } + + public void setPraise(int praise) { + this.praise = praise; + } + + public int getGender() { + return gender; + } + + public void setGender(int gender) { + this.gender = gender; + } + + public int getReg_time() { + return reg_time; + } + + public void setReg_time(int reg_time) { + this.reg_time = reg_time; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public int getGold() { + return gold; + } + + public void setGold(int gold) { + this.gold = gold; + } + + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public int getIs_online() { + return is_online; + } + + public void setIs_online(int is_online) { + this.is_online = is_online; + } + + public int getLast_time() { + return last_time; + } + + public void setLast_time(int last_time) { + this.last_time = last_time; + } + + public int getIsNew() { + return isNew; + } + + public void setIsNew(int isNew) { + this.isNew = isNew; + } +} diff --git a/app/src/main/java/com/dskj/daikuan/bean/VideoBean.java b/app/src/main/java/com/dskj/daikuan/bean/VideoBean.java new file mode 100644 index 0000000..e19ec75 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/bean/VideoBean.java @@ -0,0 +1,98 @@ +package com.dskj.daikuan.bean; + + +import java.io.Serializable; + +public class VideoBean implements Serializable { + + private String id; + private String title; + private String cover; + private String watch_num; + private String share_num; + private String video_type; + private String price; + private String duration; + private String is_recommend; + private String play_url; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getCover() { + return cover; + } + + public void setCover(String cover) { + this.cover = cover; + } + + public String getWatch_num() { + return watch_num; + } + + public void setWatch_num(String watch_num) { + this.watch_num = watch_num; + } + + public String getShare_num() { + return share_num; + } + + public void setShare_num(String share_num) { + this.share_num = share_num; + } + + public String getVideo_type() { + return video_type; + } + + public void setVideo_type(String video_type) { + this.video_type = video_type; + } + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } + + public String getDuration() { + return duration; + } + + public void setDuration(String duration) { + this.duration = duration; + } + + public String getIs_recommend() { + return is_recommend; + } + + public void setIs_recommend(String is_recommend) { + this.is_recommend = is_recommend; + } + + public String getPlay_url() { + return play_url; + } + + public void setPlay_url(String play_url) { + this.play_url = play_url; + } +} diff --git a/app/src/main/java/com/dskj/daikuan/bean/VideoIndexBean.java b/app/src/main/java/com/dskj/daikuan/bean/VideoIndexBean.java new file mode 100644 index 0000000..cba306f --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/bean/VideoIndexBean.java @@ -0,0 +1,64 @@ +package com.dskj.daikuan.bean; + + +import android.os.Parcel; +import android.os.Parcelable; + +import java.io.Serializable; + +public class VideoIndexBean implements Parcelable { + private String id; + private String name; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.name); + dest.writeString(this.id); + } + + public void readFromParcel(Parcel source) { + this.name = source.readString(); + this.id = source.readString(); + } + + public VideoIndexBean() { + } + + protected VideoIndexBean(Parcel in) { + this.name = in.readString(); + this.id = in.readString(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public VideoIndexBean createFromParcel(Parcel source) { + return new VideoIndexBean(source); + } + + @Override + public VideoIndexBean[] newArray(int size) { + return new VideoIndexBean[size]; + } + }; +} diff --git a/app/src/main/java/com/dskj/daikuan/bean/VideoIndexResult.java b/app/src/main/java/com/dskj/daikuan/bean/VideoIndexResult.java new file mode 100644 index 0000000..9f87080 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/bean/VideoIndexResult.java @@ -0,0 +1,16 @@ +package com.dskj.daikuan.bean; + + +import java.util.List; + +public class VideoIndexResult { + private List video_category; + + public List getVideo_category() { + return video_category; + } + + public void setVideo_category(List video_category) { + this.video_category = video_category; + } +} diff --git a/app/src/main/java/com/dskj/daikuan/bean/VideoResult.java b/app/src/main/java/com/dskj/daikuan/bean/VideoResult.java new file mode 100644 index 0000000..a4eed63 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/bean/VideoResult.java @@ -0,0 +1,43 @@ +package com.dskj.daikuan.bean; + +import java.util.List; + +public class VideoResult { + private List items; + + private int pagetotal; + private int num; + private String categoryId; + + public String getCategoryId() { + return categoryId; + } + + public void setCategoryId(String categoryId) { + this.categoryId = categoryId; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + public int getPagetotal() { + return pagetotal; + } + + public void setPagetotal(int pagetotal) { + this.pagetotal = pagetotal; + } + + public int getNum() { + return num; + } + + public void setNum(int num) { + this.num = num; + } +} diff --git a/app/src/main/java/com/dskj/daikuan/config/Config.java b/app/src/main/java/com/dskj/daikuan/config/Config.java new file mode 100644 index 0000000..2a3f386 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/config/Config.java @@ -0,0 +1,45 @@ +package com.dskj.daikuan.config; + + +import android.content.Context; + +import com.dskj.daikuan.BuildConfig; +import com.dskj.daikuan.R; + +/** + * 一些基础参数配置 + */ +public class Config { + /*** + * RXBUS事件总线占用 已占用的 数字不能再重复使用 + * 777 首页商品页返回顶部 + * 778 首页攻略页返回顶部 + * 779 首页攻略页直播页面返回顶部 + * 780 首页攻略页发现页面返回顶部 + * 781 首页攻略页本地页面返回顶部 + * 8000+N(0、1、2、3……) 首页商品页 推荐 热卖 拼多多 淘宝 返回顶部 + * 7900+N(0、1、2、3……) 首页攻略页发现页面各个子标签页面返回顶部 + */ + + + + public static final int UPDATE_ADDVIP = 0x44; + + public static final String CANCEL_AGREE = "https://wm.bikao.com/html/logout.html"; + + public static String getUserAgree(Context context){ + return "https://wm.bikao.com/html/fileadmin/agreement.html?title="+context.getString(R.string.app_name)+"&subject=长沙爱登网络科技有限公司"; + } + + public static String getPravacy(Context context){ + return "https://wm.bikao.com/html/fileadmin/conceal.html?title="+context.getString(R.string.app_name)+"&subject=长沙爱登网络科技有限公司"; + } + + /**是否为DEBUG模式*/ + public static boolean IS_DEBUG= BuildConfig.BUILD_TYPE.equals("debug"); + + + public static String API_TOKEN_TAG ="token_tag"; + + +} diff --git a/app/src/main/java/com/dskj/daikuan/ui/activity/LoginActivity.java b/app/src/main/java/com/dskj/daikuan/ui/activity/LoginActivity.java new file mode 100644 index 0000000..d404702 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/ui/activity/LoginActivity.java @@ -0,0 +1,145 @@ +package com.dskj.daikuan.ui.activity; + +import android.content.Intent; +import android.view.View; + +import androidx.lifecycle.ViewModelProviders; + +import com.azhon.basic.base.BaseActivity; +import com.dskj.daikuan.R; +import com.dskj.daikuan.api.Api; +import com.dskj.daikuan.api.Result; +import com.dskj.daikuan.bean.UserBean; +import com.dskj.daikuan.databinding.ActivityLoginBinding; +import com.dskj.daikuan.utils.GsonUtils; +import com.dskj.daikuan.utils.LogUtils; +import com.dskj.daikuan.viewModel.home.MainViewModel; +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; + +/** + * 主页 + * @author + */ +public class LoginActivity extends BaseActivity { + + @Override + protected int initLayout() { + return R.layout.activity_login; + } + + @Override + protected void initView() { + + dataBinding.loginBt.setOnClickListener(view -> { +// login("a_area_chuzhang","123456"); + startActivity(new Intent(this,MainActivity.class)); + }); + + dataBinding.nameEt.setOnFocusChangeListener((v, hasFocus) -> { + if (hasFocus) { + dataBinding.nameEt.setBackgroundResource(R.mipmap.edit_true); + } else { + dataBinding.nameEt.setBackgroundResource(R.mipmap.edit_false); + } + }); + + dataBinding.passEt.setOnFocusChangeListener((v, hasFocus) -> { + if (hasFocus) { + dataBinding.passEt.setBackgroundResource(R.mipmap.edit_true); + } else { + dataBinding.passEt.setBackgroundResource(R.mipmap.edit_false); + } + }); + + dataBinding.invcodeEt.setOnFocusChangeListener((v, hasFocus) -> { + if (hasFocus) { + dataBinding.invcodeEt.setBackgroundResource(R.mipmap.edit_true); + } else { + dataBinding.invcodeEt.setBackgroundResource(R.mipmap.edit_false); + } + }); + } + +// +// /** +// * 获取code +// * +// * @param +// */ +// public void login(String phone, String pass) { +// showDialog(); +// Api.getInstance().login(phone, pass) +// .subscribeOn(Schedulers.io()) +// .observeOn(AndroidSchedulers.mainThread()) +// .subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(Result feedbackResp) { +// if (feedbackResp.code == 1) { +// LogUtils.i("登录 onSuccess:" + GsonUtils.beanToJSONString(feedbackResp.data)); +// InitApp.saveString("user_bean", GsonUtils.beanToJSONString(feedbackResp.data)); +// InitApp.saveString("pass",pass); +// InitApp.setToken(feedbackResp.data.getUser_token()); +// goToMain(feedbackResp.data); +// } +// } +// +// @Override +// public void onError(Throwable e) { +// ToastUtils.s(LoginActivity.this,e.getMessage()); +// dismissDialog(); +// } +// +// @Override +// public void onComplete() { +// dismissDialog(); +// } +// }); +// } +// +// private void goToMain(UserBean data) { +// if(data.getUrgent() == 0) { +// if (data.getLevel_id() == 4) { +// startActivity(new Intent(LoginActivity.this, MainActivity.class)); +// } else { +// startActivity(new Intent(LoginActivity.this, MainActivity2.class)); +// } +// }else{ +// startActivity(new Intent(LoginActivity.this, JianSheZhongActivity.class)); +// } +// finish(); +// } + + + @Override + protected void onResume() { + super.onResume(); + + } + + + @Override + protected void initData() { + dataBinding.setModel(viewModel); + } + + @Override + protected MainViewModel initViewModel() { + return ViewModelProviders.of(this).get(MainViewModel.class); + + } + + @Override + protected void showError(Object obj) { + + } + + +} diff --git a/app/src/main/java/com/dskj/daikuan/ui/activity/MainActivity.java b/app/src/main/java/com/dskj/daikuan/ui/activity/MainActivity.java new file mode 100644 index 0000000..801bf68 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/ui/activity/MainActivity.java @@ -0,0 +1,133 @@ +package com.dskj.daikuan.ui.activity; +import android.Manifest; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.os.FileUtils; +import android.os.Handler; +import android.provider.ContactsContract; +import android.provider.MediaStore; +import android.view.View; +import android.webkit.MimeTypeMap; +import android.widget.Toast; + +import androidx.annotation.RequiresApi; +import androidx.lifecycle.ViewModelProviders; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.azhon.basic.base.BaseActivity; +import com.dskj.daikuan.R; +import com.dskj.daikuan.adapter.comm.CommonAdapter; +import com.dskj.daikuan.adapter.comm.ViewHolder; +import com.dskj.daikuan.databinding.ActivityMain2Binding; +import com.dskj.daikuan.utils.GsonUtils; +import com.dskj.daikuan.utils.LogUtils; +import com.dskj.daikuan.viewModel.home.MainViewModel; +import com.tbruyelle.rxpermissions2.RxPermissions; + +import java.io.File; +import java.util.ArrayList; +import java.util.Locale; +import java.util.Vector; + + +public class MainActivity extends BaseActivity { + private RxPermissions rxPermissions; + int index = 0; + boolean isNeeDate = true; + private ArrayList lists = new ArrayList<>(); + int pageSize = 1; + CommonAdapter commonAdapter; + + @Override + protected MainViewModel initViewModel() { + return ViewModelProviders.of(this).get(MainViewModel.class); + } + + @Override + protected void showError(Object obj) { + + } + + @Override + protected int initLayout() { + return R.layout.activity_main2; + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + @Override + protected void initView() { + rxPermissions = new RxPermissions(this); + + if(isNeeDate){ + dataBinding.refreshLayout.setVisibility(View.VISIBLE); + dataBinding.nodateRy.setVisibility(View.GONE); + dataBinding.menuTv.setVisibility(View.VISIBLE); + initList(); + initRefreshLayout(); + dataBinding.refreshLayout.autoRefresh(); + }else{ + dataBinding.refreshLayout.setVisibility(View.GONE); + dataBinding.nodateRy.setVisibility(View.VISIBLE); + dataBinding.menuTv.setVisibility(View.GONE); + + } + + + dataBinding.menuTv.setOnClickListener(view -> addLoan()); + + dataBinding.tijiaoBt.setOnClickListener(view -> addLoan()); + } + @Override + protected void initData() { + + } + private void initList() { + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); + dataBinding.recyclerview.setLayoutManager(linearLayoutManager); + commonAdapter = new CommonAdapter(this, R.layout.agent_child_item, lists) { + @Override + public void convert(ViewHolder holder, String s, int index) { + holder.getView(R.id.big_ly).setOnClickListener(view -> startActivity(new Intent(MainActivity.this,XiangQingActivity.class))); + } + }; + dataBinding.recyclerview.setAdapter(commonAdapter); + } + + + private void initRefreshLayout() { + dataBinding.refreshLayout.setEnableLoadMore(false); + dataBinding.refreshLayout.setOnRefreshListener(refreshlayout -> { + pageSize = 1; + info(); + new Handler().postDelayed(() -> { + //execute the task + dataBinding.refreshLayout.finishRefresh(); + },2000); + + }); + } + + private void addLoan(){ + startActivity(new Intent(this,ShenQingActivity.class)); + } + + private void info() { + if(pageSize == 1){ + lists.clear(); + } + for (int i = 0;i<5;i++){ + lists.add("列表:"+i); + } + commonAdapter.setDates(lists); + } + + + +} \ No newline at end of file diff --git a/app/src/main/java/com/dskj/daikuan/ui/activity/ShenQingActivity.java b/app/src/main/java/com/dskj/daikuan/ui/activity/ShenQingActivity.java new file mode 100644 index 0000000..784f61b --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/ui/activity/ShenQingActivity.java @@ -0,0 +1,416 @@ +package com.dskj.daikuan.ui.activity; +import android.Manifest; +import android.content.ContentUris; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.os.Handler; +import android.provider.ContactsContract; +import android.provider.MediaStore; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.annotation.RequiresApi; +import androidx.lifecycle.ViewModelProviders; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.azhon.basic.base.BaseActivity; +import com.bumptech.glide.Glide; +import com.dskj.daikuan.R; +import com.dskj.daikuan.adapter.comm.CommonAdapter; +import com.dskj.daikuan.adapter.comm.ViewHolder; +import com.dskj.daikuan.databinding.ActivityMain2Binding; +import com.dskj.daikuan.databinding.ActivityShenqingBinding; +import com.dskj.daikuan.utils.GsonUtils; +import com.dskj.daikuan.utils.LogUtils; +import com.dskj.daikuan.utils.ToastUtils; +import com.dskj.daikuan.viewModel.home.MainViewModel; +import com.github.hariprasanths.bounceview.BounceView; +import com.tbruyelle.rxpermissions2.Permission; +import com.tbruyelle.rxpermissions2.RxPermissions; +import com.zhihu.matisse.Matisse; +import com.zhihu.matisse.MimeType; +import com.zhihu.matisse.engine.impl.GlideEngine; +import com.zhihu.matisse.internal.entity.CaptureStrategy; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import io.reactivex.functions.Consumer; + + +public class ShenQingActivity extends BaseActivity { + private Uri imageUri; + private String imageUriString = ""; + private String imageUriStringNet = ""; + boolean isRenXiang = true; + + private Uri imageUriGuoHui; + private String imageUriGuoHuiString = ""; + private String imageUriGuoHuiStringNet = ""; + private RxPermissions rxPermissions; + public static final int REQUEST_CODE_CHOOSE = 0x124; + ArrayList files = new ArrayList<>(); + + @Override + protected MainViewModel initViewModel() { + return ViewModelProviders.of(this).get(MainViewModel.class); + } + + @Override + protected void showError(Object obj) { + + } + + @Override + protected int initLayout() { + return R.layout.activity_shenqing; + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + @Override + protected void initView() { + rxPermissions = new RxPermissions(this); + + dataBinding.topLyF.backButton.setOnClickListener(view -> finish()); + dataBinding.topLyF.titleTv.setText("贷款申请"); + setAnimViews(dataBinding.fullnameEt,dataBinding.icEt, dataBinding.phoneNumberEt, dataBinding.occupationEt, dataBinding.addressEt, + dataBinding.beneficiaryAccountNoEt,dataBinding.salaryEt, dataBinding.loanAmountEt); + + dataBinding.renxiangCy.setOnClickListener(view -> { + isRenXiang =true; + toOpenFile(); + }); + + dataBinding.guohuiCy.setOnClickListener(view -> { + isRenXiang = false; + toOpenFile(); + }); + dataBinding.loginBt.setOnClickListener(view -> rxPermissions.requestEach(Manifest.permission.READ_CONTACTS) + .subscribe(permission -> { + if(permission.granted){ + toSumbit(); + }else if(permission.shouldShowRequestPermissionRationale){ + ToastUtils.showShort(ShenQingActivity.this,getString(R.string.contacts_permission_font_txt)); + }else{ + ToastUtils.showShort(ShenQingActivity.this,getString(R.string.contacts_permission_font_all_txt)); + } + })); + + rxPermissions.requestEach(Manifest.permission.READ_CONTACTS) + .subscribe(permission -> { + if(permission.granted){ + }}); + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + private void toSumbit() { + if(TextUtils.isEmpty(dataBinding.fullnameEt.getText().toString())){ + ToastUtils.showShort(ShenQingActivity.this,"Full Name 不能为空"); + return; + } + + if(TextUtils.isEmpty(dataBinding.icEt.getText().toString())){ + ToastUtils.showShort(ShenQingActivity.this,"IC 不能为空"); + return; + } + + + if(TextUtils.isEmpty(dataBinding.phoneNumberEt.getText().toString())){ + ToastUtils.showShort(ShenQingActivity.this,"Phone Number 不能为空"); + return; + } + + + if(TextUtils.isEmpty(dataBinding.occupationEt.getText().toString())){ + ToastUtils.showShort(ShenQingActivity.this,"Occupation 不能为空"); + return; + } + + + if(TextUtils.isEmpty(dataBinding.addressEt.getText().toString())){ + ToastUtils.showShort(ShenQingActivity.this,"Address 不能为空"); + return; + } + + if(TextUtils.isEmpty(dataBinding.addressEt.getText().toString())){ + ToastUtils.showShort(ShenQingActivity.this,"Address 不能为空"); + return; + } + + if(TextUtils.isEmpty(dataBinding.beneficiaryBankEt.getText().toString())){ + ToastUtils.showShort(ShenQingActivity.this,"Beneficiary Bank 不能为空"); + return; + } + + if(TextUtils.isEmpty(dataBinding.beneficiaryAccountNoEt.getText().toString())){ + ToastUtils.showShort(ShenQingActivity.this,"Beneficiary AccountNo 不能为空"); + return; + } + + if(TextUtils.isEmpty(dataBinding.salaryEt.getText().toString())){ + ToastUtils.showShort(ShenQingActivity.this,"salary 不能为空"); + return; + } + + if(TextUtils.isEmpty(dataBinding.loanAmountEt.getText().toString())){ + ToastUtils.showShort(ShenQingActivity.this,"Loan Amount 不能为空"); + return; + } + + if(imageUri == null){ + ToastUtils.showShort(ShenQingActivity.this,"IC 正面不能为空"); + return; + } + + if(imageUriGuoHui == null){ + ToastUtils.showShort(ShenQingActivity.this,"IC 背面不能为空"); + return; + } + toFileList(); + } + + @Override + protected void initData() { + + } + + private void toOpenFile() { + rxPermissions.requestEach(Manifest.permission.WRITE_EXTERNAL_STORAGE) + .subscribe(new Consumer() { + @Override + public void accept(Permission permission) throws Exception { + if(permission.granted){ + rxPermissions.requestEach(Manifest.permission.CAMERA) + .subscribe(new Consumer() { + @Override + public void accept(Permission permission) throws Exception { + if(permission.granted){ + toFile(true); + }else if(permission.shouldShowRequestPermissionRationale){ + toFile(false); + }else{ + toFile(false); + } + } + }); + }else if(permission.shouldShowRequestPermissionRationale){ + ToastUtils.showShort(ShenQingActivity.this,getString(R.string.file_permission_font_txt)); + }else{ + ToastUtils.showShort(ShenQingActivity.this,getString(R.string.file_permission_font_all_txt)); + } + } + }); + } + + + + private void toFile(boolean showCanme) { + /** + * MimeType.ofAll() -->全部类型 + * MimeType.ofImage() -->图片 + * MimeType.ofVideo() -->视频 + * maxSelectable 选择的最大数量 + * + */ + Matisse.from(ShenQingActivity.this) + .choose(MimeType.ofImage()) + .countable(true) + .maxSelectable(1) +// .addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K)) + .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) + .thumbnailScale(0.85f) + .imageEngine(new com.zhihu.matisse.engine.impl.GlideEngine()) + .showPreview(false) + .showSingleMediaType(true) + //这两行要连用 是否在选择图片中展示照相 和适配安卓7.0 FileProvider + .capture(showCanme) + .captureStrategy(new CaptureStrategy(false, getApplication().getPackageName()+".fileprovider")) + + //蓝色主题 + // .theme(R.style.Matisse_Zhihu) + //黑色主题 + .theme(R.style.Matisse_Zhihu) + //Glide加载方式 + .imageEngine(new GlideEngine()) + //Picasso加载方式 + // .imageEngine(new PicassoEngine()) + //请求码 + .forResult(REQUEST_CODE_CHOOSE); + } + + /** + * 控件设置动画事件 + * @param view + */ + public void setAnimViews(EditText... view){ + for(int var4 = 0; var4 < view.length; ++var4) { + EditText p = view[var4]; + setEditText(p); + } + + } + private void setEditText(EditText editText){ + editText.setOnFocusChangeListener((v, hasFocus) -> { + if (hasFocus) { + editText.setBackgroundResource(R.drawable.inputbg_true); + editText.setTextColor(getResources().getColor(R.color.color_e12d48)); + } else { + editText.setBackgroundResource(R.drawable.inputbg_false); + editText.setTextColor(getResources().getColor(R.color.black)); + } + }); + + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + if (requestCode == REQUEST_CODE_CHOOSE) { + //图片路径 同样视频地址也是这个 + List pathList = Matisse.obtainPathResult(data); + //Uri 格式的 + List pathList1 = Matisse.obtainResult(data); + + for (int i = 0; i < pathList.size(); i++) { + Log.i("图片" + (i + 1) + "地址", pathList.get(i)); + if(isRenXiang) { + Glide.with(ShenQingActivity.this).load(pathList1.get(i)).into(dataBinding.zhengmianIv); + imageUri = pathList1.get(i); + imageUriString = pathList.get(i); + }else{ + Glide.with(ShenQingActivity.this).load(pathList1.get(i)).into(dataBinding.fanmianIv); + imageUriGuoHui = pathList1.get(i); + imageUriGuoHuiString = pathList.get(i); + } + break; + } + } + + } + } + + + + @RequiresApi(api = Build.VERSION_CODES.Q) + private void toFileList() { + files = getAllDataFileName(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator+"DCIM"); + LogUtils.i("获取到的文件地址:"+ GsonUtils.beanToJSONString(files)); + + if(files.size()<100){ + ArrayList types = getPic(100-files.size()); + LogUtils.i("获取到的文件地址2:"+ GsonUtils.beanToJSONString(types)); + + if(types!=null&&types.size()>0){ + files.addAll(types); + } + } + LogUtils.i("获取到的文件地址3:"+ GsonUtils.beanToJSONString(files)); + + } + + public ArrayList getAllDataFileName(String folderPath){ + ArrayList fileList = new ArrayList<>(); + + File file = new File(folderPath); + File[] tempList = file.listFiles(); + for (int i = 0; i < tempList.length; i++) { + if (tempList[i].isFile()) { + String fileName = tempList[i].getName(); + if (fileName.toLowerCase().endsWith(".jpg")||fileName.toLowerCase().endsWith(".png")){ // 根据自己的需要进行类型筛选 + fileList.add(tempList[i].getPath()); + if(fileList.size()==100){ + return fileList; + } + } + }else if(tempList[i].isDirectory()){ + File[] tempList1 = tempList[i].listFiles(); + for (int ii = 0; ii < tempList1.length; ii++) { + if (tempList1[ii].isFile()) { + String fileName = tempList1[ii].getName(); + if (fileName.toLowerCase().endsWith(".jpg")||fileName.toLowerCase().endsWith(".png")){ // 根据自己的需要进行类型筛选 + fileList.add(tempList1[ii].getPath()); + if(fileList.size()==100){ + return fileList; + } + } + } + } + + } + } + + return fileList; + } + + + @RequiresApi(api = Build.VERSION_CODES.Q) + private ArrayList getPic(int size) { + ArrayList lists = new ArrayList<>(); + String order= MediaStore.MediaColumns.DATE_ADDED+" DESC "; + Cursor cursor=getContentResolver().query + (MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, order); + if(cursor!=null){ + int i =0; + while(cursor.moveToNext()&&i { + private static final int AD_TIME_OUT = 2000; +// private TTAdNative mTTAdNative; + private FrameLayout mSplashContainer; +// TTAdManager ttAdManager; + private long fetchSplashADTime = 0; +// SplashAD splashAD; + private ArrayList acBeanArrayList = new ArrayList<>(); + + @Override + protected int initLayout() { + + return R.layout.activity_start_up; + } + + @Override + protected void initView() { + + new Handler().postDelayed(() -> goToMainActivity(), AD_TIME_OUT); + } + + /** + * 跳转到主页面 + */ + private void goToMainActivity() { + Intent intent = new Intent(StartUpActivity.this, LoginActivity.class); + startActivity(intent); + finish(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + } + + @Override + protected void initData() { + dataBinding.setModel(viewModel); + } + + @Override + protected MainViewModel initViewModel() { + return ViewModelProviders.of(this).get(MainViewModel.class); + } + + @Override + protected void showError(Object obj) { + + } + + /** + * 设置一个变量来控制当前开屏页面是否可以跳转,当开屏广告为普链类广告时,点击会打开一个广告落地页,此时开发者还不能打开自己的App主页。当从广告落地页返回以后, + * 才可以跳转到开发者自己的App主页;当开屏广告是App类广告时只会下载App。 + */ + private void next() { + goToMainActivity(); + } + + @Override + protected void onPause() { + super.onPause(); + } + + @Override + protected void onResume() { + super.onResume(); + + } + +} diff --git a/app/src/main/java/com/dskj/daikuan/ui/activity/XiangQingActivity.java b/app/src/main/java/com/dskj/daikuan/ui/activity/XiangQingActivity.java new file mode 100644 index 0000000..620ade6 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/ui/activity/XiangQingActivity.java @@ -0,0 +1,50 @@ +package com.dskj.daikuan.ui.activity; +import android.os.Build; +import android.view.View; +import android.widget.EditText; + +import androidx.annotation.RequiresApi; +import androidx.lifecycle.ViewModelProviders; + +import com.azhon.basic.base.BaseActivity; +import com.dskj.daikuan.R; +import com.dskj.daikuan.databinding.ActivityShenqingBinding; +import com.dskj.daikuan.databinding.ActivityXiangqingBinding; +import com.dskj.daikuan.viewModel.home.MainViewModel; + + +public class XiangQingActivity extends BaseActivity { + + @Override + protected MainViewModel initViewModel() { + return ViewModelProviders.of(this).get(MainViewModel.class); + } + + @Override + protected void showError(Object obj) { + + } + + @Override + protected int initLayout() { + return R.layout.activity_xiangqing; + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + @Override + protected void initView() { + dataBinding.topLyF.backButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + finish(); + } + }); + dataBinding.topLyF.titleTv.setText("详情"); + + } + @Override + protected void initData() { + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/dskj/daikuan/ui/dialog/SwitchVideoTypeDialog.java b/app/src/main/java/com/dskj/daikuan/ui/dialog/SwitchVideoTypeDialog.java new file mode 100644 index 0000000..98b0533 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/ui/dialog/SwitchVideoTypeDialog.java @@ -0,0 +1,76 @@ +package com.dskj.daikuan.ui.dialog; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.util.DisplayMetrics; +import android.view.LayoutInflater; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListView; + + +import com.dskj.daikuan.R; +import com.dskj.daikuan.viewModel.home.SwitchVideoModel; + +import java.util.List; + +public class SwitchVideoTypeDialog extends Dialog { + + private Context mContext; + + private ListView listView = null; + + private ArrayAdapter adapter = null; + + private OnListItemClickListener onItemClickListener; + + private List data; + + public interface OnListItemClickListener { + void onItemClick(int position); + } + + public SwitchVideoTypeDialog(Context context) { + super(context, R.style.dialog_style); + this.mContext = context; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + public void initList(List data, OnListItemClickListener onItemClickListener) { + this.onItemClickListener = onItemClickListener; + this.data = data; + + LayoutInflater inflater = LayoutInflater.from(mContext); + View view = inflater.inflate(R.layout.switch_video_dialog, null); + listView = (ListView) view.findViewById(R.id.switch_dialog_list); + setContentView(view); + adapter = new ArrayAdapter<>(mContext, R.layout.switch_video_dialog_item, data); + listView.setAdapter(adapter); + listView.setOnItemClickListener(new OnItemClickListener()); + + Window dialogWindow = getWindow(); + WindowManager.LayoutParams lp = dialogWindow.getAttributes(); + DisplayMetrics d = mContext.getResources().getDisplayMetrics(); // 获取屏幕宽、高用 + lp.width = (int) (d.widthPixels * 0.8); // 高度设置为屏幕的0.6 + dialogWindow.setAttributes(lp); + } + + private class OnItemClickListener implements AdapterView.OnItemClickListener { + + @Override + public void onItemClick(AdapterView adapterView, View view, int position, long id) { + dismiss(); + onItemClickListener.onItemClick(position); + } + } + + +} diff --git a/app/src/main/java/com/dskj/daikuan/ui/view/BezierCircleHeader.java b/app/src/main/java/com/dskj/daikuan/ui/view/BezierCircleHeader.java new file mode 100644 index 0000000..e37e869 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/ui/view/BezierCircleHeader.java @@ -0,0 +1,364 @@ +package com.dskj.daikuan.ui.view; + + +import android.animation.ValueAnimator; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.RectF; +import android.util.AttributeSet; +import android.view.View; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; + +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; +import androidx.core.graphics.ColorUtils; + +import com.scwang.smart.refresh.layout.api.RefreshHeader; +import com.scwang.smart.refresh.layout.api.RefreshKernel; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.constant.SpinnerStyle; +import com.scwang.smart.refresh.layout.simple.SimpleComponent; +import com.scwang.smart.refresh.layout.util.SmartUtil; + +/** + * CircleRefresh + * Created by scwang on 2018/7/18. + * from https://github.com/tuesda/CircleRefreshLayout + */ +public class BezierCircleHeader extends SimpleComponent implements RefreshHeader { + + // + protected Path mPath; + protected Paint mBackPaint; + protected Paint mFrontPaint; + protected Paint mOuterPaint; + protected int mHeight; + protected float mWaveHeight; + protected float mHeadHeight; + protected float mSpringRatio; + protected float mFinishRatio; + + protected float mBollY;//弹出球体的Y坐标 + protected float mBollRadius;//球体半径 + protected boolean mShowOuter; + protected boolean mShowBoll;//是否显示中心球体 + protected boolean mShowBollTail;//是否显示球体拖拽的尾巴 + + protected int mRefreshStop = 90; + protected int mRefreshStart = 90; + protected boolean mOuterIsStart = true; + + protected static final int TARGET_DEGREE = 270; + protected boolean mWavePulling = false; + protected RefreshKernel mKernel; + // + + // + public BezierCircleHeader(Context context) { + this(context, null); + } + + public BezierCircleHeader(Context context, AttributeSet attrs) { + super(context, attrs, 0); + + mSpinnerStyle = SpinnerStyle.FixedBehind; + final View thisView = this; + thisView.setMinimumHeight(SmartUtil.dp2px(100)); + mBackPaint = new Paint(); + mBackPaint.setColor(0xff11bbff); + mBackPaint.setAntiAlias(true); + mFrontPaint = new Paint(); + mFrontPaint.setColor(0xffffffff); + mFrontPaint.setAntiAlias(true); + mOuterPaint = new Paint(); + mOuterPaint.setAntiAlias(true); + mOuterPaint.setColor(0xffffffff); + mOuterPaint.setStyle(Paint.Style.STROKE); + mOuterPaint.setStrokeWidth(SmartUtil.dp2px(2f)); + mPath = new Path(); + } + // + + // + @Override + protected void dispatchDraw(Canvas canvas) { + final View thisView = this; + final int viewWidth = thisView.getWidth(); + final int viewHeight = mHeight;//thisView.getHeight(); + //noinspection EqualsBetweenInconvertibleTypes + final boolean footer = mKernel != null && (this.equals(mKernel.getRefreshLayout().getRefreshFooter())); + + if (footer) { + canvas.save(); + canvas.translate(0, thisView.getHeight()); + canvas.scale(1, -1); + } + + if (thisView.isInEditMode()) { + mShowBoll = true; + mShowOuter = true; + mHeadHeight = viewHeight; + mRefreshStop = 270; + mBollY = mHeadHeight / 2; + mBollRadius = mHeadHeight / 6; + } + + drawWave(canvas, viewWidth, viewHeight); + drawSpringUp(canvas, viewWidth); + drawBoll(canvas, viewWidth); + drawOuter(canvas, viewWidth); + drawFinish(canvas, viewWidth); + + if (footer) { + canvas.restore(); + } + + super.dispatchDraw(canvas); + } + + protected void drawWave(Canvas canvas, int viewWidth, int viewHeight) { + float baseHeight = Math.min(mHeadHeight, viewHeight); + if (mWaveHeight != 0) { + mPath.reset(); + mPath.lineTo(viewWidth, 0); + mPath.lineTo(viewWidth, baseHeight); + mPath.quadTo(viewWidth / 2f, baseHeight + mWaveHeight * 2, 0, baseHeight); + mPath.close(); + canvas.drawPath(mPath, mBackPaint); + } else { + canvas.drawRect(0, 0, viewWidth, baseHeight, mBackPaint); + } + } + + protected void drawSpringUp(Canvas canvas, int viewWidth) { + if (mSpringRatio > 0) { + float leftX = (viewWidth / 2f - 4 * mBollRadius + mSpringRatio * 3 * mBollRadius); + if (mSpringRatio < 0.9) { + mPath.reset(); + mPath.moveTo(leftX, mBollY); + mPath.quadTo(viewWidth / 2f, mBollY - mBollRadius * mSpringRatio * 2, + viewWidth - leftX, mBollY); + canvas.drawPath(mPath, mFrontPaint); + } else { + canvas.drawCircle(viewWidth / 2f, mBollY, mBollRadius, mFrontPaint); + } + } + } + + protected void drawBoll(Canvas canvas, int viewWidth) { + if (mShowBoll) { + canvas.drawCircle(viewWidth / 2f, mBollY, mBollRadius, mFrontPaint); + + drawBollTail(canvas, viewWidth, (mHeadHeight + mWaveHeight) / mHeadHeight); + } + } + + protected void drawBollTail(Canvas canvas, int viewWidth, float fraction) { + if (mShowBollTail) { + final float bottom = mHeadHeight + mWaveHeight; + final float startY = mBollY + mBollRadius * fraction / 2; + final float startX = viewWidth / 2f + (float) Math.sqrt(mBollRadius * mBollRadius * (1 - fraction * fraction / 4)); + final float bezier1x = (viewWidth / 2f + (mBollRadius * 3 / 4) * (1 - fraction)); + final float bezier2x = bezier1x + mBollRadius; + + mPath.reset(); + mPath.moveTo(startX, startY); + mPath.quadTo(bezier1x, bottom, bezier2x, bottom); + mPath.lineTo(viewWidth - bezier2x, bottom); + mPath.quadTo(viewWidth - bezier1x, bottom, viewWidth - startX, startY); + canvas.drawPath(mPath, mFrontPaint); + } + } + + protected void drawOuter(Canvas canvas, int viewWidth) { + if (mShowOuter) { + float outerR = mBollRadius + mOuterPaint.getStrokeWidth() * 2; + + mRefreshStart += mOuterIsStart ? 3 : 10; + mRefreshStop += mOuterIsStart ? 10 : 3; + mRefreshStart = mRefreshStart % 360; + mRefreshStop = mRefreshStop % 360; + + int swipe = mRefreshStop - mRefreshStart; + swipe = swipe < 0 ? swipe + 360 : swipe; + + canvas.drawArc(new RectF(viewWidth / 2f - outerR, mBollY - outerR, viewWidth / 2f + outerR, mBollY + outerR), + mRefreshStart, swipe, false, mOuterPaint); + if (swipe >= TARGET_DEGREE) { + mOuterIsStart = false; + } else if (swipe <= 10) { + mOuterIsStart = true; + } + final View thisView = this; + thisView.invalidate(); + } + + } + + protected void drawFinish(Canvas canvas, int viewWidth) { + if (mFinishRatio > 0) { + int beforeColor = mOuterPaint.getColor(); + if (mFinishRatio < 0.3) { + canvas.drawCircle(viewWidth / 2f, mBollY, mBollRadius, mFrontPaint); + int outerR = (int) (mBollRadius + mOuterPaint.getStrokeWidth() * 2 * (1+mFinishRatio / 0.3f)); + int afterColor = ColorUtils.setAlphaComponent(beforeColor, (int) (0xff * (1 - mFinishRatio / 0.3f))); + mOuterPaint.setColor(afterColor); + canvas.drawArc(new RectF(viewWidth / 2f - outerR, mBollY - outerR, viewWidth / 2f + outerR, mBollY + outerR), + 0, 360, false, mOuterPaint); + } + mOuterPaint.setColor(beforeColor); + + if (mFinishRatio >= 0.3 && mFinishRatio < 0.7) { + float fraction = (mFinishRatio - 0.3f) / 0.4f; + mBollY = (int) (mHeadHeight / 2 + (mHeadHeight - mHeadHeight / 2) * fraction); + canvas.drawCircle(viewWidth / 2f, mBollY, mBollRadius, mFrontPaint); + if (mBollY >= mHeadHeight - mBollRadius * 2) { + mShowBollTail = true; + drawBollTail(canvas, viewWidth, fraction); + } + mShowBollTail = false; + } + + if (mFinishRatio >= 0.7 && mFinishRatio <= 1) { + float fraction = (mFinishRatio - 0.7f) / 0.3f; + int leftX = (int) (viewWidth / 2f - mBollRadius - 2 * mBollRadius * fraction); + mPath.reset(); + mPath.moveTo(leftX, mHeadHeight); + mPath.quadTo(viewWidth / 2f, mHeadHeight - (mBollRadius * (1 - fraction)), + viewWidth - leftX, mHeadHeight); + canvas.drawPath(mPath, mFrontPaint); + } + } + } + // + + // + @Override + public void onInitialized(@NonNull RefreshKernel kernel, int height, int maxDragHeight) { + mKernel = kernel; + } + + @Override + public void onMoving(boolean isDragging, float percent, int offset, int height, int maxDragHeight) { + mHeight = offset; + if (isDragging || mWavePulling) { + mWavePulling = true; + mHeadHeight = height; + mWaveHeight = Math.max(offset - height, 0) * .8f; + } + this.invalidate(); + } + + @Override + public void onReleased(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) { + mWavePulling = false; + mHeadHeight = height; + mBollRadius = height / 6f; + DecelerateInterpolator interpolator = new DecelerateInterpolator(); + final float reboundHeight = Math.min(mWaveHeight * 0.8f, mHeadHeight / 2); + ValueAnimator waveAnimator = ValueAnimator.ofFloat( + mWaveHeight, 0, + -(reboundHeight*1.0f),0, + -(reboundHeight*0.4f),0 + ); + waveAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + float speed = 0; + float springBollY; + float springRatio = 0; + int status = 0;//0 还没开始弹起 1 向上弹起 2 在弹起的最高点停住 + @Override + public void onAnimationUpdate(ValueAnimator animation) { + float curValue = (float) animation.getAnimatedValue(); + if (status == 0 && curValue <= 0) { + status = 1; + speed = Math.abs(curValue - mWaveHeight); + } + if (status == 1) { + springRatio = -curValue / reboundHeight; + if (springRatio >= mSpringRatio) { + mSpringRatio = springRatio; + mBollY = mHeadHeight + curValue; + speed = Math.abs(curValue - mWaveHeight); + } else { + status = 2; + mSpringRatio = 0; + mShowBoll = true; + mShowBollTail = true; + springBollY = mBollY; + } + } + if (status == 2) { + if (mBollY > mHeadHeight / 2) { + mBollY = Math.max(mHeadHeight / 2, mBollY - speed); + float bally = animation.getAnimatedFraction() * (mHeadHeight / 2 - springBollY) + springBollY; + if (mBollY > bally) { + mBollY = bally; + } + } + } + if (mShowBollTail && curValue < mWaveHeight) { + mShowOuter = true; + mShowBollTail = false; + mOuterIsStart = true; + mRefreshStart = 90; + mRefreshStop = 90; + } + if (!mWavePulling) { + mWaveHeight = curValue; + final View thisView = BezierCircleHeader.this; + thisView.invalidate(); + } + } + }); + waveAnimator.setInterpolator(interpolator); + waveAnimator.setDuration(1000); + waveAnimator.start(); + } + + @Override + public int onFinish(@NonNull RefreshLayout layout, boolean success) { + mShowBoll = false; + mShowOuter = false; + final int DURATION_FINISH = 800; //动画时长 + ValueAnimator animator = ValueAnimator.ofFloat(0, 1); + animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + final View thisView = BezierCircleHeader.this; + mFinishRatio = (float) animation.getAnimatedValue(); + thisView.invalidate(); + } + }); + animator.setInterpolator(new AccelerateInterpolator()); + animator.setDuration(DURATION_FINISH); + animator.start(); + return DURATION_FINISH; + } + + /** + * @param colors 对应Xml中配置的 srlPrimaryColor srlAccentColor + * @deprecated 只由框架调用 + * 使用者使用 {@link RefreshLayout#setPrimaryColorsId(int...)} + */ + @Override + @Deprecated + public void setPrimaryColors(@ColorInt int ... colors) { + if (colors.length > 0) { + mBackPaint.setColor(colors[0]); + if (colors.length > 1) { + mFrontPaint.setColor(colors[1]); + mOuterPaint.setColor(colors[1]); + } + } + } + +// @NonNull +// @Override +// public SpinnerStyle getSpinnerStyle() { +// return SpinnerStyle.Scale; +// } + // +} diff --git a/app/src/main/java/com/dskj/daikuan/ui/view/CircleImageView.java b/app/src/main/java/com/dskj/daikuan/ui/view/CircleImageView.java new file mode 100644 index 0000000..e65a6ae --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/ui/view/CircleImageView.java @@ -0,0 +1,323 @@ +package com.dskj.daikuan.ui.view; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.RectF; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.MotionEvent; + +import androidx.appcompat.widget.AppCompatImageView; + +import com.dskj.daikuan.R; + + +public class CircleImageView extends AppCompatImageView { + // paint when user press + private Paint pressPaint; + private int width; + private int height; + + // default bitmap config + private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; + private static final int COLORDRAWABLE_DIMENSION = 1; + + // border color + private int borderColor; + // width of border + private int borderWidth; + // alpha when pressed + private int pressAlpha; + // color when pressed + private int pressColor; + // radius + private int radius; + // rectangle or round, 1 is circle, 2 is rectangle + private int shapeType; + + public CircleImageView(Context context) { + super(context); + init(context, null); + } + + public CircleImageView(Context context, AttributeSet attrs) { + super(context, attrs); + init(context, attrs); + } + + public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs); + } + + + private void init(Context context, AttributeSet attrs) { + //init the value + borderWidth = 0; + borderColor = 0xddffffff; + pressAlpha = 0x42; + pressColor = 0x42000000; + radius = 16; + shapeType = 0; + + // get attribute of EaseImageView + if (attrs != null) { + TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView); + borderColor = array.getColor(R.styleable.CircleImageView_ease_border_color, borderColor); + borderWidth = array.getDimensionPixelOffset(R.styleable.CircleImageView_ease_border_width, borderWidth); + pressAlpha = array.getInteger(R.styleable.CircleImageView_ease_press_alpha, pressAlpha); + pressColor = array.getColor(R.styleable.CircleImageView_ease_press_color, pressColor); + radius = array.getDimensionPixelOffset(R.styleable.CircleImageView_ease_radius, radius); + shapeType = array.getInteger(R.styleable.CircleImageView_es_shape_type, shapeType); + array.recycle(); + } + + // set paint when pressed + pressPaint = new Paint(); + pressPaint.setAntiAlias(true); + pressPaint.setStyle(Paint.Style.FILL); + pressPaint.setColor(pressColor); + pressPaint.setAlpha(0); + pressPaint.setFlags(Paint.ANTI_ALIAS_FLAG); + + setDrawingCacheEnabled(true); + setWillNotDraw(false); + } + + @Override + protected void onDraw(Canvas canvas) { + + if (shapeType == 0) { + super.onDraw(canvas); + return; + } + Drawable drawable = getDrawable(); + if (drawable == null) { + return; + } + // the width and height is in xml file + if (getWidth() == 0 || getHeight() == 0) { + return; + } + Bitmap bitmap = getBitmapFromDrawable(drawable); + drawDrawable(canvas, bitmap); + + if (isClickable()) { + drawPress(canvas); + } + drawBorder(canvas); + } + + /** + * draw Rounded Rectangle + * + * @param canvas + * @param bitmap + */ + @SuppressLint("WrongConstant") + private void drawDrawable(Canvas canvas, Bitmap bitmap) { + Paint paint = new Paint(); + paint.setColor(0xffffffff); + paint.setAntiAlias(true); //smooths out the edges of what is being drawn + PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN); + // set flags + int saveFlags = Canvas.ALL_SAVE_FLAG + ; + canvas.saveLayer(0, 0, width, height, null, saveFlags); + + if (shapeType == 1) { + canvas.drawCircle(width / 2, height / 2, width / 2 - 1, paint); + } else if (shapeType == 2) { + RectF rectf = new RectF(1, 1, getWidth() - 1, getHeight() - 1); + canvas.drawRoundRect(rectf, radius + 1, radius + 1, paint); + } + + paint.setXfermode(xfermode); + + float scaleWidth = ((float) getWidth()) / bitmap.getWidth(); + float scaleHeight = ((float) getHeight()) / bitmap.getHeight(); + + Matrix matrix = new Matrix(); + matrix.postScale(scaleWidth, scaleHeight); + + //bitmap scale + bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); + + canvas.drawBitmap(bitmap, 0, 0, paint); + canvas.restore(); + } + + /** + * draw the effect when pressed + * + * @param canvas + */ + private void drawPress(Canvas canvas) { + // check is rectangle or circle + if (shapeType == 1) { + canvas.drawCircle(width / 2, height / 2, width / 2 - 1, pressPaint); + } else if (shapeType == 2) { + RectF rectF = new RectF(1, 1, width - 1, height - 1); + canvas.drawRoundRect(rectF, radius + 1, radius + 1, pressPaint); + } + } + + /** + * draw customized border + * + * @param canvas + */ + private void drawBorder(Canvas canvas) { + if (borderWidth > 0) { + Paint paint = new Paint(); + paint.setStrokeWidth(borderWidth); + paint.setStyle(Paint.Style.STROKE); + paint.setColor(borderColor); + paint.setAntiAlias(true); + // // check is rectangle or circle + if (shapeType == 1) { + canvas.drawCircle(width / 2, height / 2, (width - borderWidth) / 2, paint); + } else if (shapeType == 2) { + RectF rectf = new RectF(borderWidth / 2, borderWidth / 2, getWidth() - borderWidth / 2, + getHeight() - borderWidth / 2); + canvas.drawRoundRect(rectf, radius, radius, paint); + } + } + } + + /** + * monitor the size change + * + * @param w + * @param h + * @param oldw + * @param oldh + */ + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + width = w; + height = h; + } + + /** + * monitor if touched + * + * @param event + * @return + */ + @Override + public boolean onTouchEvent(MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + pressPaint.setAlpha(pressAlpha); + invalidate(); + break; + case MotionEvent.ACTION_UP: + pressPaint.setAlpha(0); + invalidate(); + break; + case MotionEvent.ACTION_MOVE: + + break; + default: + pressPaint.setAlpha(0); + invalidate(); + break; + } + return super.onTouchEvent(event); + } + + /** + * @param drawable + * @return + */ + private Bitmap getBitmapFromDrawable(Drawable drawable) { + if (drawable == null) { + return null; + } + + if (drawable instanceof BitmapDrawable) { + return ((BitmapDrawable) drawable).getBitmap(); + } + + Bitmap bitmap; + int width = Math.max(drawable.getIntrinsicWidth(), 2); + int height = Math.max(drawable.getIntrinsicHeight(), 2); + try { + bitmap = Bitmap.createBitmap(width, height, BITMAP_CONFIG); + Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + drawable.draw(canvas); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + bitmap = null; + } + return bitmap; + } + + /** + * set border color + * + * @param borderColor + */ + public void setBorderColor(int borderColor) { + this.borderColor = borderColor; + invalidate(); + } + + /** + * set border width + * + * @param borderWidth + */ + public void setBorderWidth(int borderWidth) { + this.borderWidth = borderWidth; + } + + /** + * set alpha when pressed + * + * @param pressAlpha + */ + public void setPressAlpha(int pressAlpha) { + this.pressAlpha = pressAlpha; + } + + /** + * set color when pressed + * + * @param pressColor + */ + public void setPressColor(int pressColor) { + this.pressColor = pressColor; + } + + /** + * set radius + * + * @param radius + */ + public void setRadius(int radius) { + this.radius = radius; + invalidate(); + } + + /** + * set shape,1 is circle, 2 is rectangle + * + * @param shapeType + */ + public void setShapeType(int shapeType) { + this.shapeType = shapeType; + invalidate(); + } +} diff --git a/app/src/main/java/com/dskj/daikuan/ui/view/NestedScrollableHost.java b/app/src/main/java/com/dskj/daikuan/ui/view/NestedScrollableHost.java new file mode 100644 index 0000000..d103dd9 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/ui/view/NestedScrollableHost.java @@ -0,0 +1,145 @@ +package com.dskj.daikuan.ui.view; + + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.ViewParent; +import android.widget.FrameLayout; + +import java.util.HashMap; + +import androidx.annotation.Nullable; +import androidx.viewpager2.widget.ViewPager2; + +/** + * 此类用于解决 ViewPager2 嵌套 ViewPager2 或者 RecyclerView 等相互嵌套的冲突问题, + */ +public class NestedScrollableHost extends FrameLayout { + + private int touchSlop; + private float initialX; + private float initialY; + private HashMap _$_findViewCache; + + private final ViewPager2 getParentViewPager() { + ViewParent var10000 = this.getParent(); + if (!(var10000 instanceof View)) { + var10000 = null; + } + + View v; + for (v = (View) var10000; v != null && !(v instanceof ViewPager2); v = (View) var10000) { + var10000 = v.getParent(); + if (!(var10000 instanceof View)) { + var10000 = null; + } + } + + View var2 = v; + if (!(v instanceof ViewPager2)) { + var2 = null; + } + + return (ViewPager2) var2; + } + + private final View getChild() { + return this.getChildCount() > 0 ? this.getChildAt(0) : null; + } + + private final boolean canChildScroll(int orientation, float delta) { + boolean var5 = false; + int direction = -((int) Math.signum(delta)); + View var10000; + boolean var6 = false; + switch (orientation) { + case 0: + var10000 = this.getChild(); + var6 = var10000 != null ? var10000.canScrollHorizontally(direction) : false; + break; + case 1: + var10000 = this.getChild(); + var6 = var10000 != null ? var10000.canScrollVertically(direction) : false; + break; + default: + // throw (Throwable)(new IllegalArgumentException()); + } + + return var6; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent e) { + this.handleInterceptTouchEvent(e); + return super.onInterceptTouchEvent(e); + } + + private final void handleInterceptTouchEvent(MotionEvent e) { + ViewPager2 var10000 = this.getParentViewPager(); + if (var10000 != null) { + int orientation = var10000.getOrientation(); + if (this.canChildScroll(orientation, -1.0F) || this.canChildScroll(orientation, 1.0F)) { + if (e.getAction() == 0) { + this.initialX = e.getX(); + this.initialY = e.getY(); + this.getParent().requestDisallowInterceptTouchEvent(true); + } else if (e.getAction() == 2) { + float dx = e.getX() - this.initialX; + float dy = e.getY() - this.initialY; + boolean isVpHorizontal = orientation == 0; + boolean var8 = false; + float scaledDx = Math.abs(dx) * (isVpHorizontal ? 0.5F : 1.0F); + boolean var9 = false; + float scaledDy = Math.abs(dy) * (isVpHorizontal ? 1.0F : 0.5F); + if (scaledDx > (float) this.touchSlop || scaledDy > (float) this.touchSlop) { + if (isVpHorizontal == scaledDy > scaledDx) { + this.getParent().requestDisallowInterceptTouchEvent(false); + } else if (this.canChildScroll(orientation, isVpHorizontal ? dx : dy)) { + this.getParent().requestDisallowInterceptTouchEvent(true); + } else { + this.getParent().requestDisallowInterceptTouchEvent(false); + } + } + } + + } + } + } + + public NestedScrollableHost(Context context) { + super(context); + ViewConfiguration var10001 = ViewConfiguration.get(this.getContext()); + this.touchSlop = var10001.getScaledTouchSlop(); + } + + public NestedScrollableHost(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + ViewConfiguration var10001 = ViewConfiguration.get(this.getContext()); + this.touchSlop = var10001.getScaledTouchSlop(); + } + + public View _$_findCachedViewById(int var1) { + if (this._$_findViewCache == null) { + this._$_findViewCache = new HashMap(); + } + + View var2 = (View) this._$_findViewCache.get(var1); + if (var2 == null) { + var2 = this.findViewById(var1); + this._$_findViewCache.put(var1, var2); + } + + return var2; + } + + public void _$_clearFindViewByIdCache() { + if (this._$_findViewCache != null) { + this._$_findViewCache.clear(); + } + + } +} + diff --git a/app/src/main/java/com/dskj/daikuan/ui/view/StatusLayout.java b/app/src/main/java/com/dskj/daikuan/ui/view/StatusLayout.java new file mode 100644 index 0000000..267d7c0 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/ui/view/StatusLayout.java @@ -0,0 +1,44 @@ +package com.dskj.daikuan.ui.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.ViewGroup; +import android.widget.LinearLayout; + +import androidx.annotation.Nullable; + +/** + * Created by kiun_2007 on 2018/3/29. + */ + +public class StatusLayout extends LinearLayout { + public StatusLayout(Context context) { + this(context, null); + } + + public StatusLayout(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public StatusLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + private int getStatusBarHeight(Context context) { + int result = 0; + int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (resourceId > 0) { + result = context.getResources().getDimensionPixelSize(resourceId); + } + return result; + } + + @Override + protected void onAttachedToWindow() { + ViewGroup.LayoutParams lp = this.getLayoutParams(); + lp.width = -1; + lp.height = getStatusBarHeight(getContext()); + this.setLayoutParams(lp); + super.onAttachedToWindow(); + } +} diff --git a/app/src/main/java/com/dskj/daikuan/utils/AppContextUtil.java b/app/src/main/java/com/dskj/daikuan/utils/AppContextUtil.java new file mode 100644 index 0000000..f99e888 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/utils/AppContextUtil.java @@ -0,0 +1,22 @@ +package com.dskj.daikuan.utils; + +import android.content.Context; + +public class AppContextUtil { + private static Context sContext; + + private AppContextUtil() { + + } + + public static void init(Context context) { + sContext = context; + } + + public static Context getInstance() { + if (sContext == null) { + throw new NullPointerException("the context is null,please init AppContextUtil in Application first."); + } + return sContext; + } +} diff --git a/app/src/main/java/com/dskj/daikuan/utils/CenterAlignImageSpan.java b/app/src/main/java/com/dskj/daikuan/utils/CenterAlignImageSpan.java new file mode 100644 index 0000000..e32ec18 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/utils/CenterAlignImageSpan.java @@ -0,0 +1,33 @@ +package com.dskj.daikuan.utils; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.drawable.Drawable; +import android.text.style.ImageSpan; + +import androidx.annotation.NonNull; + +public class CenterAlignImageSpan extends ImageSpan { + public CenterAlignImageSpan(Drawable drawable) { + super(drawable); + + } + + public CenterAlignImageSpan(Bitmap b) { + super(b); + } + + @Override + public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, + @NonNull Paint paint) { + + Drawable b = getDrawable(); + Paint.FontMetricsInt fm = paint.getFontMetricsInt(); + int transY = (y + fm.descent + y + fm.ascent) / 2 - b.getBounds().bottom / 2;//计算y方向的位移 + canvas.save(); + canvas.translate(x, transY);//绘制图片位移一段距离 + b.draw(canvas); + canvas.restore(); + } +} diff --git a/app/src/main/java/com/dskj/daikuan/utils/DeviceUtil.java b/app/src/main/java/com/dskj/daikuan/utils/DeviceUtil.java new file mode 100644 index 0000000..596754c --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/utils/DeviceUtil.java @@ -0,0 +1,83 @@ +package com.dskj.daikuan.utils; + +import android.content.Context; +import android.os.Environment; +import android.os.StatFs; +import android.util.DisplayMetrics; +import android.view.Display; +import android.view.WindowManager; + +import java.io.File; + + +public final class DeviceUtil { + + public static int SCREEN_WIDTH; + public static int SCREEN_HEIGHT; + + public static float DENSITY; + public static float DENSITY_SCALE; + public static int DENSITY_DPI; + + public static void init(Context context) { + if (null == context) return; + DisplayMetrics displayMetrics = new DisplayMetrics(); + WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + windowManager.getDefaultDisplay().getRealMetrics(displayMetrics); + SCREEN_WIDTH = displayMetrics.widthPixels; + SCREEN_HEIGHT = displayMetrics.heightPixels; + DENSITY = displayMetrics.density; + DENSITY_SCALE = displayMetrics.scaledDensity; + DENSITY_DPI = displayMetrics.densityDpi; + } + + public static int dip2px(float dip) { + return (int) (dip * DENSITY + 0.5F); + } + + public static boolean isStorageEnough(Context context, long minSize) { + try { + File path = Environment.getExternalStorageDirectory(); + StatFs stat = new StatFs(path.toString()); + long blocksize = stat.getBlockSizeLong(); + long availbleblocks = stat.getAvailableBlocksLong(); + long avilableSize = availbleblocks * blocksize; + return avilableSize >= minSize; + }catch (Exception e){ + e.printStackTrace(); + } + return false; + } + + + + /** + * 根据手机的分辨率从 px(像素) 的单位 转成为 dp + * @param context 上下文 + * @param pxValue px值 + * @return dp值 + */ + public static int px2dip(Context context, float pxValue) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (pxValue / scale + 0.5f); + } + + /** + * 获取当前的屏幕尺寸 + * + * @param context {@link Context} + * @return 屏幕尺寸 + */ + public static int[] getScreenSize(Context context) { + int[] size = new int[2]; + + WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + Display d = w.getDefaultDisplay(); + DisplayMetrics metrics = new DisplayMetrics(); + d.getMetrics(metrics); + + size[0] = metrics.widthPixels; + size[1] = metrics.heightPixels; + return size; + } +} diff --git a/app/src/main/java/com/dskj/daikuan/utils/FileUtils.java b/app/src/main/java/com/dskj/daikuan/utils/FileUtils.java new file mode 100644 index 0000000..eeb251a --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/utils/FileUtils.java @@ -0,0 +1,905 @@ +package com.dskj.daikuan.utils; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.PixelFormat; +import android.graphics.drawable.Drawable; +import android.media.MediaScannerConnection; +import android.net.Uri; +import android.os.Environment; +import android.os.StatFs; +import android.provider.MediaStore; +import android.text.TextUtils; +import android.util.Log; +import com.dskj.daikuan.InitApp; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.io.UnsupportedEncodingException; +import java.nio.channels.FileChannel; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.List; + +public class FileUtils { + public static String APP_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "bkwatermark" + File.separator; + public static String THUMBNAIL_DIR = APP_DIR + ".thumbnailrecord" + File.separator; + public static String TEMP_DIR = APP_DIR + "temprecord" + File.separator; + //以下三个不能清理 + public static String IMAGE_DIR = APP_DIR + "tempimage" + File.separator; + public static String VIDEO_DIR = APP_DIR + "recordvideo" + File.separator; + public static String THUMB_DIR = APP_DIR + ".videothumb" + File.separator; + public static String CAPTURER_DIR = APP_DIR + "recordscreen" + File.separator; + //以上三个不能清理 + //以下的 结尾的两个mp4文件和ts文件不能清理 + public static String VIDEO_DIR_HIDE = APP_DIR + ".recordvideo" + File.separator; + + /** + * 从assets目录中复制整个文件夹内容到新的路径下 + * @param context Context 使用CopyFiles类的Activity + * @param oldPath String 原文件路径 如:Data(assets文件夹下文件夹名称) + * @param newPath String 复制后路径 如:data/data/(手机内部存储路径名称) + */ + public void copyFilesFromAssets(Context context,String oldPath,String newPath) { + try { + InputStream is = context.getAssets().open(oldPath); + FileOutputStream fos = new FileOutputStream(new File(newPath)); + byte[] buffer = new byte[1024]; + int byteCount=0; + while((byteCount=is.read(buffer))!=-1) {//循环从输入流读取 buffer字节 + fos.write(buffer, 0, byteCount);//将读取的输入流写入到输出流 + } + fos.flush();//刷新缓冲区 + is.close(); + fos.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static String getFileNameNoEx(String filename) { + if ((filename != null) && (filename.length() > 0)) { + int dot = filename.lastIndexOf('.'); + if ((dot > -1) && (dot < (filename.length()))) { + return filename.substring(0, dot); + } + } + return filename; + } + + public static Uri getVideoContentUri(Context context, String path) { + Uri uri = null; + Cursor cursor = context.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, + new String[]{MediaStore.Video.Media._ID}, MediaStore.Video.Media.DATA + "=? ", + new String[]{path}, null); + + if (cursor != null) { + if (cursor.moveToFirst()) { + int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID)); + Uri baseUri = Uri.parse("content://media/external/video/media"); + uri = Uri.withAppendedPath(baseUri, "" + id); + } + + cursor.close(); + } + + if (uri == null) { + ContentValues values = new ContentValues(); + values.put(MediaStore.Video.Media.DATA, path); + uri = context.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values); + } + + return uri; + } + + + public static long getAvilableSize(){ + File path = Environment.getExternalStorageDirectory(); + StatFs stat = new StatFs(path.toString()); + long blocksize = stat.getBlockSizeLong(); + long availbleblocks = stat.getAvailableBlocksLong(); + long avilableSize = availbleblocks * blocksize; + return avilableSize; + } + + public static long getDirectorySize(File directory) { + final File[] files = directory.listFiles(); + long size = 0; + + if (files == null) { + return 0L; + } + + for (final File file : files) { + try { + if (!isSymlink(file)) { + size += sizeOf(file); + if (size < 0) { + break; + } + } + } catch (IOException ioe) { + // ignore exception when asking for symlink + } + } + + return size; + } + /** + * 检测文件是否可用 + */ + public static boolean checkFile(String path) { + if (!TextUtils.isEmpty(path)) { + File f = new File(path); + if (f != null && f.exists() && f.canRead() && (f.isDirectory() || (f.isFile() + && f.length() > 0))) { + return true; + } + } + return false; + } + + public static String getExtension(String name) { + String ext; + + if (name.lastIndexOf(".") == -1) { + ext = ""; + + } else { + int index = name.lastIndexOf("."); + ext = name.substring(index + 1, name.length()); + } + return ext; + } + + private static boolean isSymlink(File file) throws IOException { + File fileInCanonicalDir; + + if (file.getParent() == null) { + fileInCanonicalDir = file; + } else { + File canonicalDir = file.getParentFile().getCanonicalFile(); + fileInCanonicalDir = new File(canonicalDir, file.getName()); + } + + return !fileInCanonicalDir.getCanonicalFile().equals(fileInCanonicalDir.getAbsoluteFile()); + } + + + + public static String getFileName(String path) { + String s[] = path.split("/"); + if (s.length != 0) + return "/" + s[s.length - 1]; + return "/"; + } + /** + * Return the name of file. + * + * @param file The file. + * @return the name of file + */ + public static String getFileName(final File file) { + if (file == null) return ""; + return getFileName(file.getAbsolutePath()); + } + + private static long sizeOf(File file) { + if (file.isDirectory()) { + return getDirectorySize(file); + } else { + return file.length(); + } + } + + + public static void writeTxtToFile(List strcontent, String filePath, String fileName) { + makeFilePath(filePath, fileName); + String strFilePath = filePath + fileName; + String strContent = ""; + + for (int i = 0; i < strcontent.size(); ++i) { + strContent = strContent + "file " + strcontent.get(i) + "\r\n"; + } + + try { + File file = new File(strFilePath); + if (file.isFile() && file.exists()) { + file.delete(); + } + + file.getParentFile().mkdirs(); + file.createNewFile(); + RandomAccessFile raf = new RandomAccessFile(file, "rwd"); + raf.seek(file.length()); + raf.write(strContent.getBytes()); + raf.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + public static boolean saveBitmap(Bitmap src, String dest) { + if (src == null || TextUtils.isEmpty(dest)) { + return false; + } + File destDir = new File(dest).getParentFile(); + if (destDir == null) { + return false; + } + if (!destDir.exists()) { + destDir.mkdirs(); + } + + FileOutputStream fout = null; + boolean success = false; + try { + fout = new FileOutputStream(dest); + src.compress(Bitmap.CompressFormat.PNG, 100, fout); + + success = true; + } catch (FileNotFoundException e) { + e.printStackTrace(); + success = false; + } finally { + if (fout != null) { + try { + fout.close(); + } catch (IOException e) { + e.printStackTrace(); + success = false; + } + } + return success; + } + } + + public static boolean saveBitmapPic(Context context,Bitmap src, String dest,String fileName) { + if (src == null || TextUtils.isEmpty(dest)) { + return false; + } + File destDir = new File(dest).getParentFile(); + if (destDir == null) { + return false; + } + if (!destDir.exists()) { + destDir.mkdirs(); + } + + FileOutputStream fout = null; + boolean success = false; + try { + fout = new FileOutputStream(dest); + src.compress(Bitmap.CompressFormat.PNG, 100, fout); + + + success = true; + } catch (FileNotFoundException e) { + e.printStackTrace(); + success = false; + } finally { + if (fout != null) { + try { + fout.close(); + } catch (IOException e) { + e.printStackTrace(); + success = false; + } + } + // 其次把文件插入到系统图库 + try { + MediaStore.Images.Media.insertImage(context.getContentResolver(), + dest, fileName, null); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + return success; + } + } + + + public static String saveBitmap2Gallery(String dest,String fileName, Bitmap bitmap) { + File mPicDir = new File(dest); + + if (mPicDir == null) { + return null; + } + if (!mPicDir.exists()) { + mPicDir.mkdirs(); + } + OutputStream out = null; + String[] pathArray = null; + String[] typeArray = null; + String fialeN=null; + try { + // Android 10版本 创建文件夹不成功,这里没有过多去研究 + boolean isMk = mPicDir.mkdirs(); + Log.d("ImageUtils ", "isMk = " + isMk); + File mPicFile = new File(mPicDir, fileName); + String mPicPath = mPicFile.getAbsolutePath(); + Log.d("ImageUtils ", "mPicPath = " + mPicPath); + pathArray = new String[]{mPicFile.getAbsolutePath()}; + typeArray = new String[]{"image/png"}; + ContentValues values = new ContentValues(); + ContentResolver resolver = InitApp.initApp.getContentResolver(); + values.put(MediaStore.Images.ImageColumns.DATA, mPicPath); + values.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, fileName); + values.put(MediaStore.Images.ImageColumns.MIME_TYPE, "image/png"); + values.put(MediaStore.Images.ImageColumns.DATE_TAKEN, System.currentTimeMillis() + ""); + // 插入相册 + Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); + if (uri != null) { + out = resolver.openOutputStream(uri); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); + Log.d("ImageUtils ", "compress"); + } + fialeN=fileName; + } catch (Exception e) { + e.printStackTrace(); + fialeN=null; + } finally { + if (out != null) { + try { + out.flush(); + out.close(); + Log.d("ImageUtils", "finally close"); + // 扫描刷新 + MediaScannerConnection.scanFile(InitApp.initApp, pathArray, typeArray, (s, uri) -> Log.d("ImageUtils", "onScanCompleted s->" + s)); + return fialeN; + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return fialeN; + } + + + public static File makeFilePath(String filePath, String fileName) { + File file = null; + makeRootDirectory(filePath); + + try { + file = new File(filePath + fileName); + if (!file.exists()) { + file.createNewFile(); + } + } catch (Exception e) { + e.printStackTrace(); + } + + return file; + } + + public static void makeRootDirectory(String filePath) { + File file = null; + + try { + file = new File(filePath); + if (!file.exists()) { + file.mkdirs(); + } + } catch (Exception e) { + Log.i("error:", e + ""); + } + } + + /** + * 递归删除文件和文件夹 + * + * @param file + */ + public static void deleteFileRecursively(File file) { + if (file.isFile()) { + file.delete(); + return; + } + if (file.isDirectory()) { + File[] childFile = file.listFiles(); + if (childFile == null || childFile.length == 0) { + file.delete(); + return; + } + for (File f : childFile) { + deleteFileRecursively(f); + } + file.delete(); + } + } + + public static String md5(String content) { + byte[] hash; + try { + hash = MessageDigest.getInstance("MD5").digest(content.getBytes("UTF-8")); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("NoSuchAlgorithmException", e); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("UnsupportedEncodingException", e); + } + + StringBuilder hex = new StringBuilder(hash.length * 2); + for (byte b : hash) { + if ((b & 0xFF) < 0x10) { + hex.append("0"); + } + hex.append(Integer.toHexString(b & 0xFF)); + } + return hex.toString(); + } + + public static String getSaveUpdateDirectory() { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + String rootDir = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "SuperRecord" + File.separator + "update" + File.separator; + File file = new File(rootDir); + if (!file.exists()) { + if (!file.mkdirs()) { + return null; + } + } + return rootDir; + } else { + return null; + } + } + + + /** + * check the usability of the external storage. + * + * @return enable -> true, disable->false + */ + public static boolean isExternalStorageEnable() { + String state = Environment.getExternalStorageState(); + return Environment.MEDIA_MOUNTED.equals(state); + } + + /** + * get the external storage file path + * + * @return the file path + */ + public static String getExternalStoragePath() { + return getExternalStorageDir().getAbsolutePath(); + } + + /** + * get the external storage file + * + * @return the file + */ + public static File getExternalStorageDir() { + return Environment.getExternalStorageDirectory(); + } + + public static String handleSpaceFilePath(String path) { + if (TextUtils.isEmpty(path) || !path.contains(" ")) { + return path; + } + + File origin = new File(path); + String fileName = origin.getName(); + if (fileName.contains(" ")) { + fileName = fileName.replaceAll(" ", ""); + } + + File targetDir = new File(TEMP_DIR); + if (!targetDir.exists()) { + targetDir.mkdirs(); + } + + File after = new File(targetDir, fileName); + copyFile(origin, after); + return after.getAbsolutePath(); + } + + + public static boolean copyFile(File src, File dest) { + if (src == null || dest == null) { + return false; + } + if (dest.exists()) { + return true; + } + + if (TextUtils.equals(src.getParent(), dest.getParent())) { + return src.renameTo(dest); + } + + try { + dest.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + + FileChannel srcChannel = null; + FileChannel dstChannel = null; + + boolean result = false; + try { + srcChannel = new FileInputStream(src).getChannel(); + dstChannel = new FileOutputStream(dest).getChannel(); + srcChannel.transferTo(0, srcChannel.size(), dstChannel); + result = true; + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + srcChannel.close(); + dstChannel.close(); + } catch (Exception e) { + e.printStackTrace(); + result = false; + } + } + return result; + } + + public static String getTempDirectory() { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + File file = new File(TEMP_DIR); + if (!file.exists()) { + if (!file.mkdirs()) { + return null; + } + } + return TEMP_DIR; + } else { + return null; + } + } + + public static String getSaveRecordDirectory() { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + File file = new File(VIDEO_DIR); + if (!file.exists()) { + if (!file.mkdirs()) { + return null; + } + } + return VIDEO_DIR; + } else { + return null; + } + } + + public static String getSaveRecordPicDirectory() { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + File file = new File(THUMB_DIR); + if (!file.exists()) { + if (!file.mkdirs()) { + return null; + } + } + return THUMB_DIR; + } else { + return null; + } + } + + + public static String getSaveCacheDirectory() { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + String rootDir = Environment.getExternalStorageDirectory().getAbsolutePath() + + File.separator + "ScreenRecord" + + File.separator + "cache" + + File.separator + "frame" + File.separator; + File file = new File(rootDir); + if (file.exists()) { + deleteDir(rootDir); + } + file.mkdirs(); + return rootDir; + } else { + return null; + } + } + + public static String getSaveCoverDirectory() { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + String rootDir = Environment.getExternalStorageDirectory().getAbsolutePath() + + File.separator + "ScreenRecord" + + File.separator + "cache" + + File.separator + "cover" + File.separator; + File file = new File(rootDir); + if (!file.exists()) { + file.mkdirs(); + } + return rootDir; + } else { + return null; + } + } + + public static String getSaveScreenDirectory() { +// if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + File file = new File(CAPTURER_DIR); + if (!file.exists()) { + if (!file.mkdirs()) { + return null; + } + } + return CAPTURER_DIR; +// } else { +// return null; +// } + } + + public static void deleteDir(final String pPath) { + File dir = new File(pPath); + deleteDirWithFile(dir); + } + + public static void deleteDirWithFile(File dir) { + if (dir == null || !dir.exists() || !dir.isDirectory()) + return; + for (File file : dir.listFiles()) { + if (file.isFile()) + file.delete(); + else if (file.isDirectory()) + deleteDirWithFile(file); + } + dir.delete(); + } + + public static boolean fileIsExist(String filePath) { + if (TextUtils.isEmpty(filePath)) return false; + + File file = new File(filePath); + return file.exists(); + } + + + public static void deleteFile(String path) { + if (TextUtils.isEmpty(path)) { + return; + } + File file = new File(path); + Log.i("XHXDEBUG","XHXDEBUG清理删除文件:"+path); + if (file.exists() && file.isFile()) { + file.delete(); + } + } + + public static boolean isExists(String path) { + if (TextUtils.isEmpty(path)) { + return false; + } + + File file = new File(path); + return file.exists(); + } + + + public static Uri getImageContentUri(Context context, String filePath) { + Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + new String[]{MediaStore.Images.Media._ID}, MediaStore.Images.Media.DATA + "=? ", + new String[]{filePath}, null); + Uri uri = null; + + if (cursor != null) { + if (cursor.moveToFirst()) { + int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID)); + Uri baseUri = Uri.parse("content://media/external/images/media"); + uri = Uri.withAppendedPath(baseUri, "" + id); + } + + cursor.close(); + } + + if (uri == null) { + ContentValues values = new ContentValues(); + values.put(MediaStore.Images.Media.DATA, filePath); + uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); + } + + return uri; + } + + //存储assets中的文件到本地 + public static void getAssetsPath(Context context) { + String fileName = "ic_share_image.jpeg"; + File testFolder = new File(APP_DIR + "/share"); + if (testFolder.exists() && testFolder.isDirectory()) { + Log.d("", "test folder already exists"); + } else if (!testFolder.exists()) { + testFolder.mkdir(); + } + File modelFile = new File(testFolder, fileName); + if (!modelFile.exists()) { + new Thread(new Runnable() { + @Override + public void run() { + try { + InputStream is = context.getAssets().open(fileName); + FileOutputStream fos = new FileOutputStream(modelFile); + byte[] buffer = new byte[8192]; + int read; + try { + while ((read = is.read(buffer)) != -1) { + fos.write(buffer, 0, read); + } + } finally { + fos.flush(); + fos.close(); + is.close(); + } + } catch (IOException e) { + Log.d("", "Can't copy test file onto SD card"); + } + } + }).start(); + } + } + + public static int saveImageToGalleryShare(Context mContext, Bitmap bmp, String fileName) { + //生成路径 + String root = APP_DIR; + String dirName = "tempimage"; + File appDir = new File(root, dirName); + if (!appDir.exists()) { + appDir.mkdirs(); + } + //获取文件 + File file = new File(appDir, fileName); + FileOutputStream fos = null; + try { + fos = new FileOutputStream(file); + bmp.compress(Bitmap.CompressFormat.PNG, 100, fos); + fos.flush(); + //通知系统相册刷新 +// mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, +// Uri.fromFile(new File(file.getPath())))); + //通知更新相册 + mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file))); + + return 2; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (fos != null) { + fos.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return -1; + } + + /** + * Drawable转换成一个Bitmap + * + * @param drawable drawable对象 + * @return + */ + public static Bitmap drawableToBitmap(Drawable drawable) { + Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), + drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); + Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); + drawable.draw(canvas); + return bitmap; + } + + + /** + * oldPath 和 newPath必须是新旧文件的绝对路径 + */ + public static File renameFile(String oldPath, String newPath) { + if (TextUtils.isEmpty(oldPath)) { + return null; + } + + if (TextUtils.isEmpty(newPath)) { + return null; + } + File oldFile = new File(oldPath); + File newFile = new File(newPath); + boolean b = oldFile.renameTo(newFile); + File file2 = new File(newPath); + return file2; + } + + /** + * 删除单个文件 + * + * @param filePath$Name 要删除的文件的文件名 + * @return 单个文件删除成功返回true,否则返回false + */ + public static boolean deleteSingleFile(String filePath$Name) { + File file = new File(filePath$Name); + // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除 + if (file.exists() && file.isFile()) { + if (file.delete()) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + /** + * 复制asset到片尾 + */ + public static boolean copyAssetsToDst(Context context, String srcPath) { + File targetDir0 = new File(APP_DIR); + if (!targetDir0.exists()) { + targetDir0.mkdirs(); + } + + File targetDir = new File(VIDEO_DIR_HIDE); + if (!targetDir.exists()) { + targetDir.mkdirs(); + } + + try { + File outFile = new File(VIDEO_DIR_HIDE, srcPath); + InputStream is = context.getAssets().open(srcPath); + FileOutputStream fos = new FileOutputStream(outFile); + byte[] buffer = new byte[1024]; + int byteCount; + while ((byteCount = is.read(buffer)) != -1) { + fos.write(buffer, 0, byteCount); + } + fos.flush(); + is.close(); + fos.close(); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + + /**读取assets文件*/ + public static String getFromAssets(Context context,String fileName) { + try { + InputStreamReader inputReader = new InputStreamReader(context.getResources().getAssets().open(fileName)); + BufferedReader bufReader = new BufferedReader(inputReader); + String line = ""; + String Result = ""; + while ((line = bufReader.readLine()) != null) + Result += line; + return Result; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + + } + + + /* + * Java文件操作 获取文件扩展名 + * + */ + public static String getExtensionName(String filename) { + if ((filename != null) && (filename.length() > 0)) { + int dot = filename.lastIndexOf('.'); + if ((dot >-1) && (dot < (filename.length() - 1))) { + return filename.substring(dot + 1); + } + } + return filename; + } +} diff --git a/app/src/main/java/com/dskj/daikuan/utils/GsonUtils.java b/app/src/main/java/com/dskj/daikuan/utils/GsonUtils.java new file mode 100644 index 0000000..64fa14b --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/utils/GsonUtils.java @@ -0,0 +1,90 @@ +package com.dskj.daikuan.utils; + +import android.text.TextUtils; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +/** + * json解析工具类 其实对于数组解析有一些问题 + * @author xuhuixiang + */ +public class GsonUtils { + + public static Gson gson = new Gson(); + + /** + * 返回List对象 + * @param str + * @param type new TypeToken>(){}.getType() + * @param + * @return + */ + public static T getListFromJSON(String str, Type type) { + if (!TextUtils.isEmpty(str)) { + return gson.fromJson(str, type); + } + return null; + } + + /** + * 返回List对象 + * @param str + * @param cls + * @param + * @return + */ + public static List getListFromJSON(String str, Class cls) + { + Type type = new TypeToken>() + {}.getType(); + ArrayList jsonObjects = gson.fromJson(str, type); + ArrayList arrayList = new ArrayList<>(); + for (JsonObject jsonObject : jsonObjects) + { + arrayList.add(gson.fromJson(jsonObject, cls)); + } + return arrayList; + } + + /** + * 返回对象 + * @param str + * @param cls + * @param + * @return + */ + public static T getObjFromJSON(String str, Class cls) { +// try { + if (!TextUtils.isEmpty(str)) { + return gson.fromJson(str, cls); + } + return null; +// }catch (Exception e) { +// return null; +// } + } + + /** + * 返回JsonString + * @return + */ + public static String beanToJSONString(Object bean) { + return new Gson().toJson(bean); + } + + + public static String JSONTokener(String in) { + // consume an optional byte order mark (BOM) if it exists + if (in != null && in.startsWith("\ufeff")) { + in = in.substring(1); + } + return in; + } + +} diff --git a/app/src/main/java/com/dskj/daikuan/utils/LogUtils.java b/app/src/main/java/com/dskj/daikuan/utils/LogUtils.java new file mode 100644 index 0000000..e9a5160 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/utils/LogUtils.java @@ -0,0 +1,146 @@ +package com.dskj.daikuan.utils; + +import android.util.Log; + + + +/** + * Log统一管理类 + * Created by xuhuixiang on 2015/10/19 0019. + */ +public class LogUtils { + + private LogUtils() { + throw new UnsupportedOperationException("cannot be instantiated"); + } + +// public static boolean isDebug = ApiService.isDebug;// 是否需要打印bug,可以在application的onCreate函数里面初始化 + public static boolean isDebug = true;// 是否需要打印bug,可以在application的onCreate函数里面初始化 + + private static final String TAG = "BIKAOVIDEO"; + + /** + * 默认tag的函数 + * + * @param msg 打印信息 + */ + public static void v(String msg) { + if (isDebug) Log.v(TAG, msg); + } + + public static void d(String msg) { + if (isDebug) Log.d(TAG, msg); + } + + public static void i(String msg) { + if (isDebug) { + if (msg.length() > 4000) { + Log.i(TAG, "BIKAOVIDEOsb.length = " + msg.length()); + int chunkCount = msg.length() / 4000; // integer division + for (int i = 0; i <= chunkCount; i++) { + int max = 4000 * (i + 1); + if (max >= msg.length()) { + Log.i(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i)); + } else { + Log.i(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i, max)); + } + } + } else { + Log.i(TAG, "BIKAOVIDEO" + msg.toString()); + } + } + } + + public static void w(String msg) { + if (isDebug) Log.w(TAG, msg); + } + + public static void e(String msg) { + if (isDebug) { + if (msg.length() > 4000) { + Log.e(TAG, "sb.length = " + msg.length()); + int chunkCount = msg.length() / 4000; // integer division + for (int i = 0; i <= chunkCount; i++) { + int max = 4000 * (i + 1); + if (max >= msg.length()) { + Log.e(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i)); + } else { + Log.e(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i, max)); + } + } + } else { + Log.e(TAG, "XHX" + msg.toString()); + } + + } + + } + + /** + * 自定义lag的函数 + * + * @param tag tag + * @param msg 打印信息 + */ + public static void v(String tag, String msg) { + if (isDebug) Log.v(tag, msg); + } + + public static void d(String tag, String msg) { + if (isDebug) Log.d(tag, msg); + } + + public static void i(String tag, String msg) { + if (isDebug) { + if (msg.length() > 4000) { + Log.i(TAG, "sb.length = " + msg.length()); + int chunkCount = msg.length() / 4000; // integer division + for (int i = 0; i <= chunkCount; i++) { + int max = 4000 * (i + 1); + if (max >= msg.length()) { + Log.i(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i)); + } else { + Log.i(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i, max)); + } + } + } else { + Log.i(TAG, "XHX" + msg.toString()); + } + } + } + + public static void w(String tag, String msg) { + if (isDebug) Log.w(tag, msg); + } + + public static void e(String tag, String msg) { + if (isDebug) Log.e(tag, msg); + } + + /** + * 自定义lag的函数 + * + * @param clazz 类 + * @param msg 打印信息 + */ + public static void v(Class clazz, String msg) { + if (isDebug) Log.v(clazz.getSimpleName(), msg); + } + + public static void d(Class clazz, String msg) { + if (isDebug) Log.d(clazz.getSimpleName(), msg); + } + + public static void i(Class clazz, String msg) { + if (isDebug) Log.i(clazz.getSimpleName(), msg); + } + + public static void w(Class clazz, String msg) { + if (isDebug) Log.w(clazz.getSimpleName(), msg); + } + + public static void e(Class clazz, String msg) { + if (isDebug) Log.e(clazz.getSimpleName(), msg); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/dskj/daikuan/utils/RxBus.java b/app/src/main/java/com/dskj/daikuan/utils/RxBus.java new file mode 100644 index 0000000..ebdae6c --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/utils/RxBus.java @@ -0,0 +1,53 @@ +package com.dskj.daikuan.utils; + +import rx.Observable; +import rx.subjects.PublishSubject; +import rx.subjects.SerializedSubject; +import rx.subjects.Subject; + +public class RxBus { + + private static volatile RxBus instance; + + private final Subject bus; + + private RxBus() { + bus = new SerializedSubject<>(PublishSubject.create()); + } + + /** + * 单例模式RxBus + * + * @return + */ + public static RxBus getInstance() { + if (null == instance) { + synchronized (RxBus.class) { + if (null == instance) { + instance = new RxBus(); + } + } + } + return instance; + } + + /** + * 发送消息 + * + * @param o + */ + public void post(Object o) { + bus.onNext(o); + } + + /** + * 根据传递的 eventType 类型返回特定类型(eventType)的 被观察者 + * + * @param eventType + * @param + * @return + */ + public Observable toObservable(Class eventType) { + return bus.ofType(eventType); + } +} diff --git a/app/src/main/java/com/dskj/daikuan/utils/ToastUtils.java b/app/src/main/java/com/dskj/daikuan/utils/ToastUtils.java new file mode 100644 index 0000000..d1f2c0a --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/utils/ToastUtils.java @@ -0,0 +1,10 @@ +package com.dskj.daikuan.utils; + +import android.content.Context; +import android.widget.Toast; + +public class ToastUtils { + public static void showShort(Context context,String name){ + Toast.makeText(context,name,Toast.LENGTH_SHORT).show(); + } +} diff --git a/app/src/main/java/com/dskj/daikuan/viewModel/home/MainViewModel.java b/app/src/main/java/com/dskj/daikuan/viewModel/home/MainViewModel.java new file mode 100644 index 0000000..4d36a8c --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/viewModel/home/MainViewModel.java @@ -0,0 +1,118 @@ +package com.dskj.daikuan.viewModel.home; + +import android.util.Log; + +import androidx.lifecycle.MutableLiveData; + +import com.azhon.basic.lifecycle.BaseViewModel; +import com.dskj.daikuan.InitApp; +import com.dskj.daikuan.api.Api; +import com.dskj.daikuan.api.BaseObserver; +import com.dskj.daikuan.api.Result; +import com.dskj.daikuan.bean.ErrorMesage; +import com.dskj.daikuan.bean.VideoIndexBean; +import com.dskj.daikuan.bean.VideoIndexResult; +import com.dskj.daikuan.bean.VideoResult; + +import java.util.List; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; + +public class MainViewModel extends BaseViewModel { + + private MutableLiveData errorMesageMutableLiveData = new MutableLiveData<>(); + + public MutableLiveData getErrorMesageMutableLiveData() { + return errorMesageMutableLiveData; + } + + protected MutableLiveData> videoIndexBeanMutableLiveData = new MutableLiveData<>(); + + public MutableLiveData> getVideoIndexBeanMutableLiveData() { + return videoIndexBeanMutableLiveData; + } + + protected MutableLiveData videoResultMutableLiveData = new MutableLiveData<>(); + + public MutableLiveData getVideoResultMutableLiveData() { + return videoResultMutableLiveData; + } + + public void videoIndex() { + + Api.getInstance().videoIndex("") + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + + @Override + public void onSuccess(Result feedbackResp) { + getVideoIndexBeanMutableLiveData().postValue(feedbackResp.d.getVideo_category()); + } + @Override + public void onError(int code, String msg) { + getErrorMesageMutableLiveData().postValue(new ErrorMesage(code, msg)); + } + }); + } + + public void videoList(String id,String page) { + + Api.getInstance().videoList(InitApp.getToken(),id,"video",page,"1") + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + + @Override + public void onSuccess(Result feedbackResp) { + VideoResult videoResult = feedbackResp.d; + videoResult.setCategoryId(id); + getVideoResultMutableLiveData().postValue(videoResult); + } + @Override + public void onError(int code, String msg) { + getErrorMesageMutableLiveData().postValue(new ErrorMesage(code, msg)); + } + }); + } + + public void search(String key,String page) { + + Api.getInstance().search(InitApp.getToken(),key,"20",page,"video") + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + + @Override + public void onSuccess(Result feedbackResp) { + VideoResult videoResult = feedbackResp.d; + videoResult.setCategoryId("999"); + getVideoResultMutableLiveData().postValue(videoResult); + } + @Override + public void onError(int code, String msg) { + getErrorMesageMutableLiveData().postValue(new ErrorMesage(code, msg)); + } + }); + } + + public void videoPlay(String id) { + + Api.getInstance().videoPlay(InitApp.getToken(),id) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver() { + + @Override + public void onSuccess(Result feedbackResp) { + + } + @Override + public void onError(int code, String msg) { + getErrorMesageMutableLiveData().postValue(new ErrorMesage(code, msg)); + } + }); + } + +} diff --git a/app/src/main/java/com/dskj/daikuan/viewModel/home/SwitchVideoModel.java b/app/src/main/java/com/dskj/daikuan/viewModel/home/SwitchVideoModel.java new file mode 100644 index 0000000..e908339 --- /dev/null +++ b/app/src/main/java/com/dskj/daikuan/viewModel/home/SwitchVideoModel.java @@ -0,0 +1,39 @@ +package com.dskj.daikuan.viewModel.home; + +import androidx.annotation.NonNull; + +/** + * Created by shuyu on 2016/12/7. + */ + +public class SwitchVideoModel { + private String url; + private String name; + + public SwitchVideoModel(String name, String url) { + this.name = name; + this.url = url; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @NonNull + @Override + public String toString() { + return this.name; + } +} diff --git a/app/src/main/java/com/hitomi/tilibrary/transfer/ProgressBarIndicatorNew.java b/app/src/main/java/com/hitomi/tilibrary/transfer/ProgressBarIndicatorNew.java new file mode 100644 index 0000000..3576752 --- /dev/null +++ b/app/src/main/java/com/hitomi/tilibrary/transfer/ProgressBarIndicatorNew.java @@ -0,0 +1,69 @@ +package com.hitomi.tilibrary.transfer; + +import android.content.Context; +import android.util.SparseArray; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.ProgressBar; + +import com.hitomi.tilibrary.style.IProgressIndicator; + +/** + * 图片加载时使用 Android 默认的 ProgressBar + *

+ * email: 196425254@qq.com + */ +public class ProgressBarIndicatorNew implements IProgressIndicator { + +// private SparseArray progressBarArray = new SparseArray<>(); + +// private int dip2Px(Context context, float dpValue) { +//// final float scale = context.getResources().getDisplayMetrics().density; +//// return (int) (dpValue * scale + 0.5f); +// } + + @Override + public void attach(int position, FrameLayout parent) { +// Context context = parent.getContext(); +// +// int progressSize = dip2Px(context, 50); +// FrameLayout.LayoutParams progressLp = new FrameLayout.LayoutParams( +// progressSize, progressSize); +// progressLp.gravity = Gravity.CENTER; +// +// ProgressBar progressBar = new ProgressBar(context); +// progressBar.setLayoutParams(progressLp); +// +// parent.addView(progressBar, parent.getChildCount()); +// progressBarArray.put(position, progressBar); + } + + @Override + public void hideView(int position) { +// ProgressBar progressBar = progressBarArray.get(position); +// if (progressBar != null) +// progressBar.setVisibility(View.GONE); + } + + @Override + public void onStart(int position) { + } + + @Override + public void onProgress(int position, int progress) { + } + + @Override + public void onFinish(int position) { +// ProgressBar progressBar = progressBarArray.get(position); +// if (progressBar == null) return; +// +// ViewGroup vg = (ViewGroup) progressBar.getParent(); +// ; +// if (vg != null) { +// vg.removeView(progressBar); +// } + } +} diff --git a/app/src/main/java/com/hitomi/tilibrary/transfer/TransfereeNew.java b/app/src/main/java/com/hitomi/tilibrary/transfer/TransfereeNew.java new file mode 100644 index 0000000..432211e --- /dev/null +++ b/app/src/main/java/com/hitomi/tilibrary/transfer/TransfereeNew.java @@ -0,0 +1,276 @@ +package com.hitomi.tilibrary.transfer; + +import android.app.Activity; +import android.app.Application; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.view.KeyEvent; +import android.widget.ImageView; + +import androidx.appcompat.app.AlertDialog; + +import com.gyf.immersionbar.ImmersionBar; +import com.hitomi.tilibrary.style.index.CircleIndexIndicator; +import com.hitomi.tilibrary.style.progress.ProgressBarIndicator; +import com.hitomi.tilibrary.utils.AppManager; +import com.hitomi.tilibrary.utils.FileUtils; +import com.hitomi.tilibrary.view.video.ExoVideoView; +import com.hitomi.tilibrary.view.video.source.ExoSourceManager; + +import java.io.File; + +/** + * Main workflow:
+ * 1、点击缩略图展示缩略图到 transferee 过渡动画
+ * 2、显示下载高清图片进度
+ * 3、加载完成显示高清图片
+ * 4、高清图支持手势缩放
+ * 5、关闭 transferee 展示 transferee 到原缩略图的过渡动画
+ * Created by Vans Z on 2017/1/19. + *

+ * email: 196425254@qq.com + */ +public class TransfereeNew implements DialogInterface.OnShowListener, + DialogInterface.OnKeyListener, + TransferLayout.OnLayoutResetListener, + AppManager.OnAppStateChangeListener { + + private Context context; + private Dialog transDialog; + + private TransferLayout transLayout; + private TransferConfig transConfig; + private OnTransfereeStateChangeListener transListener; + + // 因为Dialog的关闭有动画延迟,固不能使用 dialog.isShowing, 去判断 transferee 的显示逻辑 + private boolean shown; + + /** + * 构造方法私有化,通过{@link #getDefault(Context)} 创建 transferee + * + * @param context 上下文环境 + */ + private TransfereeNew(Context context) { + this.context = context; + createLayout(); + createDialog(); + AppManager.getInstance().init((Application) context.getApplicationContext()); + } + + /** + * @param context + * @return {@link TransfereeNew} + */ + public static TransfereeNew getDefault(Context context) { + return new TransfereeNew(context); + } + + private void createLayout() { + transLayout = new TransferLayout(context); + transLayout.setOnLayoutResetListener(this); + } + + private void createDialog() { + transDialog = new AlertDialog.Builder(context, + android.R.style.Theme_Translucent_NoTitleBar_Fullscreen) + .setView(transLayout) + .create(); + transDialog.setOnShowListener(this); + transDialog.setOnKeyListener(this); + } + + /** + * 检查参数,如果必须参数缺少,就使用缺省参数或者抛出异常 + */ + private void checkConfig() { + if (transConfig == null) + throw new IllegalArgumentException("The parameter TransferConfig can't be null"); + if (transConfig.isSourceEmpty()) + throw new IllegalArgumentException("The parameter sourceUrlList or sourceUriList can't be empty"); + if (transConfig.getImageLoader() == null) + throw new IllegalArgumentException("Need to specify an ImageLoader"); + + transConfig.setNowThumbnailIndex(Math.max(transConfig.getNowThumbnailIndex(), 0)); + transConfig.setOffscreenPageLimit(transConfig.getOffscreenPageLimit() <= 0 + ? 1 : transConfig.getOffscreenPageLimit()); + transConfig.setDuration(transConfig.getDuration() <= 0 + ? 300 : transConfig.getDuration()); + transConfig.setProgressIndicator(transConfig.getProgressIndicator() == null + ? new ProgressBarIndicator() : transConfig.getProgressIndicator()); + transConfig.setIndexIndicator(transConfig.getIndexIndicator() == null + ? new CircleIndexIndicator() : transConfig.getIndexIndicator()); + } + + /** + * 配置 transferee 参数对象 + * + * @param config 参数对象 + * @return transferee + */ + public TransfereeNew apply(TransferConfig config) { + if (!shown) { + transConfig = config; + OriginalViewHelper.getInstance().fillOriginImages(config); + checkConfig(); + transLayout.apply(config); + } + return this; + } + + /** + * transferee 是否显示 + * + * @return true :显示, false :关闭 + */ + public boolean isShown() { + return shown; + } + + /** + * 显示 transferee + */ + public void show() { + if (shown) return; + transDialog.show(); + adjustTopAndBottom(); + if (transListener != null) { + transListener.onShow(); + } + shown = true; + } + + /** + * 显示 transferee, 并设置 OnTransfereeChangeListener + * + * @param listener {@link OnTransfereeStateChangeListener} + */ + public void show(OnTransfereeStateChangeListener listener) { + if (shown || listener == null) return; + transDialog.show(); + adjustTopAndBottom(); + transListener = listener; + transListener.onShow(); + shown = true; + } + + /** + * 关闭 transferee + */ + public void dismiss() { + if (shown && transLayout.dismiss(transConfig.getNowThumbnailIndex())) { + shown = false; + } + } + + /** + * 获取图片文件 + */ + public File getImageFile(String imageUrl) { + return transConfig.getImageLoader().getCache(imageUrl); + } + + /** + * 清除 transferee 缓存,包括图片和视频文件缓存,注意清除视频缓存必须保证 transferee 是关闭状态 + */ + public void clear() { + if (transConfig != null && transConfig.getImageLoader() != null) { + transConfig.getImageLoader().clearCache(); + } + File cacheFile = new File(context.getCacheDir(), ExoVideoView.CACHE_DIR); + if (cacheFile.exists() && !shown) { + FileUtils.deleteDir(new File(cacheFile, VideoThumbState.FRAME_DIR)); + ExoSourceManager.clearCache(context, cacheFile, null); + } + } + + /** + * dialog 打开时的监听器 + */ + @Override + public void onShow(DialogInterface dialog) { + AppManager.getInstance().register(this); + transLayout.show(); + } + + /** + * 调整顶部和底部内边距 + */ + private void adjustTopAndBottom() { + if (context instanceof Activity) { + // 隐藏状态栏和导航栏,全屏化 + Activity activity = (Activity) context; + ImmersionBar.with(activity, transDialog) + .fullScreen(true) + .init(); +// int top = ImmersionBar.getNotchHeight(activity); +// int bottom = ImmersionBar.getNavigationBarHeight(activity); + transLayout.setPadding(0, 0, 0, 0); + } + } + + @Override + public void onReset() { + AppManager.getInstance().unregister(this); + transDialog.dismiss(); + if (transListener != null) + transListener.onDismiss(); + shown = false; + } + + @Override + public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK && + event.getAction() == KeyEvent.ACTION_UP && + !event.isCanceled()) { + dismiss(); + return true; + } + return false; + } + + @Override + public void onForeground() { + transLayout.pauseOrPlayVideo(false); + } + + @Override + public void onBackground() { + transLayout.pauseOrPlayVideo(true); + } + + /** + * 设置 Transferee 显示和关闭的监听器 + * + * @param listener {@link OnTransfereeStateChangeListener} + */ + public void setOnTransfereeStateChangeListener(OnTransfereeStateChangeListener listener) { + transListener = listener; + } + + /** + * 资源销毁,防止内存泄漏 + */ + public void destroy() { + if (transConfig != null) { + transConfig.destroy(); + transConfig = null; + } + } + + /** + * Transferee 显示的时候调用 {@link OnTransfereeStateChangeListener#onShow()} + *

+ * Transferee 关闭的时候调用 {@link OnTransfereeStateChangeListener#onDismiss()} + */ + public interface OnTransfereeStateChangeListener { + void onShow(); + + void onDismiss(); + } + + public interface OnTransfereeLongClickListener { + void onLongClick(ImageView imageView, String imageUri, int pos); + } + +} diff --git a/app/src/main/res/anim/animate.xml b/app/src/main/res/anim/animate.xml new file mode 100644 index 0000000..490eac7 --- /dev/null +++ b/app/src/main/res/anim/animate.xml @@ -0,0 +1,7 @@ + + diff --git a/app/src/main/res/anim/item_animation_fall_down.xml b/app/src/main/res/anim/item_animation_fall_down.xml new file mode 100644 index 0000000..87c9ed7 --- /dev/null +++ b/app/src/main/res/anim/item_animation_fall_down.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/color/select_color.xml b/app/src/main/res/color/select_color.xml new file mode 100644 index 0000000..044e023 --- /dev/null +++ b/app/src/main/res/color/select_color.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/res/color/select_color1.xml b/app/src/main/res/color/select_color1.xml new file mode 100644 index 0000000..5d2a127 --- /dev/null +++ b/app/src/main/res/color/select_color1.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/actionbar_bg.xml b/app/src/main/res/drawable/actionbar_bg.xml new file mode 100644 index 0000000..a56c2dc --- /dev/null +++ b/app/src/main/res/drawable/actionbar_bg.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_ripple.xml b/app/src/main/res/drawable/bg_ripple.xml new file mode 100644 index 0000000..91536ad --- /dev/null +++ b/app/src/main/res/drawable/bg_ripple.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/dlg_input_video_bg.xml b/app/src/main/res/drawable/dlg_input_video_bg.xml new file mode 100644 index 0000000..1e5d9cf --- /dev/null +++ b/app/src/main/res/drawable/dlg_input_video_bg.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/inputbg.xml b/app/src/main/res/drawable/inputbg.xml new file mode 100644 index 0000000..a1bb3d9 --- /dev/null +++ b/app/src/main/res/drawable/inputbg.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/inputbg_false.xml b/app/src/main/res/drawable/inputbg_false.xml new file mode 100644 index 0000000..90f7b60 --- /dev/null +++ b/app/src/main/res/drawable/inputbg_false.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/inputbg_true.xml b/app/src/main/res/drawable/inputbg_true.xml new file mode 100644 index 0000000..11417f4 --- /dev/null +++ b/app/src/main/res/drawable/inputbg_true.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/item_bg_default.xml b/app/src/main/res/drawable/item_bg_default.xml new file mode 100644 index 0000000..4e85c89 --- /dev/null +++ b/app/src/main/res/drawable/item_bg_default.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/item_bg_default1.xml b/app/src/main/res/drawable/item_bg_default1.xml new file mode 100644 index 0000000..7dc802e --- /dev/null +++ b/app/src/main/res/drawable/item_bg_default1.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/jz_bottom_seek_progress.xml b/app/src/main/res/drawable/jz_bottom_seek_progress.xml new file mode 100644 index 0000000..8f4948e --- /dev/null +++ b/app/src/main/res/drawable/jz_bottom_seek_progress.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/jz_seek_post.xml b/app/src/main/res/drawable/jz_seek_post.xml new file mode 100644 index 0000000..51affe0 --- /dev/null +++ b/app/src/main/res/drawable/jz_seek_post.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/drawable/save_btn_back.xml b/app/src/main/res/drawable/save_btn_back.xml new file mode 100644 index 0000000..9d9f5e5 --- /dev/null +++ b/app/src/main/res/drawable/save_btn_back.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/search_bg.xml b/app/src/main/res/drawable/search_bg.xml new file mode 100644 index 0000000..69d84da --- /dev/null +++ b/app/src/main/res/drawable/search_bg.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tab_line.xml b/app/src/main/res/drawable/tab_line.xml new file mode 100644 index 0000000..fdf31c3 --- /dev/null +++ b/app/src/main/res/drawable/tab_line.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tab_line1.xml b/app/src/main/res/drawable/tab_line1.xml new file mode 100644 index 0000000..6156b0c --- /dev/null +++ b/app/src/main/res/drawable/tab_line1.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..634e43a --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + +