From f8db723bdbcdb084d3e09510be05f2666a2493d2 Mon Sep 17 00:00:00 2001 From: lijia Date: Fri, 26 Aug 2022 17:34:43 +0800 Subject: [PATCH] =?UTF-8?q?kotlin=E8=BD=AC=E5=8C=962?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mylibrary/.gitignore | 1 + mylibrary/build.gradle | 99 + mylibrary/consumer-rules.pro | 0 mylibrary/proguard-rules.pro | 21 + .../dahe/mylibrary/ExampleInstrumentedTest.kt | 24 + mylibrary/src/main/AndroidManifest.xml | 28 + .../com/dahe/mylibrary/CommonBaseLibrary.java | 137 ++ .../dahe/mylibrary/adapter/CarAdapter.java | 31 + .../mylibrary/adapter/CenterSimAdapter.java | 41 + .../mylibrary/adapter/GridImageAdapter.java | 272 +++ .../dahe/mylibrary/adapter/NodeAdapter.java | 30 + .../mylibrary/adapter/SelectDicAdapter.java | 38 + .../com/dahe/mylibrary/base/BaseActivity.java | 250 +++ .../com/dahe/mylibrary/base/BaseFragment.java | 321 ++++ .../java/com/dahe/mylibrary/bean/CarBean.java | 100 + .../com/dahe/mylibrary/bean/DictBean.java | 154 ++ .../com/dahe/mylibrary/bean/NodeBean.java | 354 ++++ .../com/dahe/mylibrary/bean/StateBean.java | 151 ++ .../com/dahe/mylibrary/bean/TipsBean.java | 29 + .../com/dahe/mylibrary/bean/VersionBean.java | 93 + .../callback/OnItemLongClickListener.java | 14 + .../mylibrary/callback/RefreshCallBack.java | 14 + .../mylibrary/cuspop/CarSelPopupView.java | 105 + .../mylibrary/cuspop/CenterPopupView.java | 91 + .../mylibrary/cuspop/CustomDicPopView.java | 90 + .../cuspop/CustomPartShadowPopupView.java | 90 + .../dahe/mylibrary/cuspop/InputPopupView.java | 80 + .../dahe/mylibrary/cuspop/NodePopupView.java | 107 ++ .../mylibrary/cuspop/TextPopupTipsView.java | 77 + .../dahe/mylibrary/cuspop/TextPopupView.java | 74 + .../mylibrary/dialog/DialogPhotoSelect.java | 108 ++ .../dahe/mylibrary/dialog/MyBaseDialog.java | 55 + .../dahe/mylibrary/dialog/VersionDialog.java | 21 + .../dahe/mylibrary/glide/AppGlideModule.java | 35 + .../mylibrary/glide/UnsafeOkHttpClient.java | 67 + .../mylibrary/net/CommonResponseBean.java | 73 + .../com/dahe/mylibrary/net/ErrorResponse.java | 22 + .../dahe/mylibrary/net/FileInterceptor.java | 60 + .../net/GsonResponseBodyConverter.java | 74 + .../dahe/mylibrary/net/JsonInterceptor.java | 67 + .../com/dahe/mylibrary/net/JsonUtils.java | 91 + .../com/dahe/mylibrary/net/PagerBean.java | 47 + .../com/dahe/mylibrary/net/PagingBean.java | 46 + .../net/ResponseConverterFactory.java | 44 + .../dahe/mylibrary/net/ResultException.java | 12 + .../GridSpacingItemDecoration.java | 43 + .../recycleviewswipe/MyDecoration.java | 110 ++ .../recycleviewswipe/RecycleViewDivider.java | 156 ++ .../dahe/mylibrary/utils/ActivityUtils.java | 330 ++++ .../com/dahe/mylibrary/utils/AppUtils.java | 1062 ++++++++++ .../com/dahe/mylibrary/utils/BarUtils.java | 678 +++++++ .../com/dahe/mylibrary/utils/Base64Utils.java | 13 + .../com/dahe/mylibrary/utils/BaseSPUtils.java | 193 ++ .../com/dahe/mylibrary/utils/BaseUtils.java | 243 +++ .../dahe/mylibrary/utils/CNPinyinIndex.java | 76 + .../dahe/mylibrary/utils/ConvertUtils.java | 645 +++++++ .../mylibrary/utils/CountDownTimerUtils.java | 38 + .../dahe/mylibrary/utils/CrashHandler.java | 243 +++ .../com/dahe/mylibrary/utils/FileUtil.java | 89 + .../com/dahe/mylibrary/utils/ImageLoader.java | 204 ++ .../dahe/mylibrary/utils/LocationUtil.java | 325 ++++ .../com/dahe/mylibrary/utils/MD5Utils.java | 60 + .../dahe/mylibrary/utils/MemoryConstants.java | 28 + .../dahe/mylibrary/utils/PatternUtils.java | 28 + .../utils/PhoneFormatCheckUtils.java | 55 + .../mylibrary/utils/SelectPhotoUtils4.java | 366 ++++ .../mylibrary/utils/SelectPhotoUtils5.java | 353 ++++ .../mylibrary/utils/SelectPhotoUtils6.java | 318 +++ .../com/dahe/mylibrary/utils/ShellUtils.java | 201 ++ .../dahe/mylibrary/utils/SmsTimeUtils.java | 148 ++ .../com/dahe/mylibrary/utils/StatusBar.java | 111 ++ .../utils/StatusBarCompatKitKat.java | 221 +++ .../utils/StatusBarCompatLollipop.java | 193 ++ .../com/dahe/mylibrary/utils/StringUtils.java | 99 + .../dahe/mylibrary/utils/TimeConstants.java | 44 + .../com/dahe/mylibrary/utils/TimeUtil.java | 1703 +++++++++++++++++ .../com/dahe/mylibrary/utils/TimingX.java | 145 ++ .../com/dahe/mylibrary/utils/ToastUtils.java | 37 + .../dahe/mylibrary/utils/VersionUtils.java | 181 ++ .../mylibrary/wapper/SelectSimAdapter.java | 37 + .../dahe/mylibrary/weight/AttachButton.java | 157 ++ .../weight/FullyGridLayoutManager.java | 104 + .../weight/GlideCircleWithBorder.java | 67 + .../dahe/mylibrary/weight/GlideEngine.java | 233 +++ .../GridSectionAverageGapItemDecoration.java | 231 +++ .../mylibrary/weight/MovedImageButton.java | 93 + .../com/dahe/mylibrary/weight/MySlideBar.java | 191 ++ .../com/dahe/mylibrary/weight/SideBar.java | 130 ++ .../com/dahe/mylibrary/weight/SwitchView.java | 508 +++++ .../weight/segmentcontrol/RadiusDrawable.java | 139 ++ .../weight/segmentcontrol/SegmentControl.java | 526 +++++ .../src/main/res/anim/anim_bottom_in.xml | 11 + .../src/main/res/anim/anim_bottom_out.xml | 9 + .../src/main/res/color/select_text_color.xml | 7 + mylibrary/src/main/res/drawable-hdpi/left.png | Bin 0 -> 489 bytes .../main/res/drawable-xhdpi/black_back.png | Bin 0 -> 1331 bytes .../src/main/res/drawable-xhdpi/fab_add.png | Bin 0 -> 229 bytes .../main/res/drawable-xhdpi/ic_add_image.png | Bin 0 -> 897 bytes .../main/res/drawable-xhdpi/icon_upload.png | Bin 0 -> 1421 bytes .../src/main/res/drawable-xhdpi/left.png | Bin 0 -> 575 bytes .../src/main/res/drawable-xxhdpi/cars.png | Bin 0 -> 1339 bytes .../src/main/res/drawable-xxhdpi/cha.png | Bin 0 -> 751 bytes .../main/res/drawable-xxhdpi/check_nor.png | Bin 0 -> 869 bytes .../main/res/drawable-xxhdpi/check_sel.png | Bin 0 -> 1650 bytes .../src/main/res/drawable-xxhdpi/diss.png | Bin 0 -> 1099 bytes .../src/main/res/drawable-xxhdpi/empty.png | Bin 0 -> 54696 bytes .../src/main/res/drawable-xxhdpi/error.png | Bin 0 -> 5425 bytes .../src/main/res/drawable-xxhdpi/fab_add.png | Bin 0 -> 323 bytes .../main/res/drawable-xxhdpi/icon_refuse.png | Bin 0 -> 1173 bytes .../main/res/drawable-xxhdpi/id_select.png | Bin 0 -> 6680 bytes .../res/drawable-xxhdpi/id_select_loading.png | Bin 0 -> 6169 bytes .../main/res/drawable-xxhdpi/id_select_z.png | Bin 0 -> 5435 bytes .../src/main/res/drawable-xxhdpi/left.png | Bin 0 -> 1006 bytes .../src/main/res/drawable-xxhdpi/message.png | Bin 0 -> 1518 bytes mylibrary/src/main/res/drawable-xxhdpi/ok.png | Bin 0 -> 4040 bytes .../main/res/drawable-xxhdpi/update_head.png | Bin 0 -> 128567 bytes .../res/drawable-xxhdpi/version_top_bg.png | Bin 0 -> 126943 bytes .../src/main/res/drawable-xxxhdpi/left.png | Bin 0 -> 1149 bytes .../res/drawable-xxxhdpi/version_top_bg.png | Bin 0 -> 164954 bytes .../src/main/res/drawable/bnav_shape_du.xml | 13 + .../main/res/drawable/bnav_tab_background.xml | 7 + mylibrary/src/main/res/drawable/loading.xml | 7 + .../main/res/drawable/select_check_node.xml | 6 + .../src/main/res/drawable/select_sim_text.xml | 7 + .../main/res/drawable/select_slide_title.xml | 7 + .../src/main/res/drawable/select_text_c.xml | 7 + .../src/main/res/drawable/shadow_bg.9.png | Bin 0 -> 1736 bytes mylibrary/src/main/res/drawable/shape_bg8.xml | 8 + .../drawable/shape_bind_phone_background.xml | 12 + .../src/main/res/drawable/shape_blue_bg10.xml | 15 + .../src/main/res/drawable/shape_blue_bg25.xml | 15 + .../src/main/res/drawable/shape_blue_bg4.xml | 12 + .../src/main/res/drawable/shape_blue_bg8.xml | 13 + .../main/res/drawable/shape_bottom_bgw16.xml | 8 + .../src/main/res/drawable/shape_gray_bg10.xml | 15 + .../src/main/res/drawable/shape_gray_bg25.xml | 15 + .../src/main/res/drawable/shape_gray_bg4.xml | 12 + .../main/res/drawable/shape_log_btn_bg22.xml | 10 + .../src/main/res/drawable/shape_message.xml | 9 + .../main/res/drawable/shape_text_4_blue.xml | 17 + .../main/res/drawable/shape_text_4_nor.xml | 17 + .../src/main/res/drawable/shape_view_v.xml | 16 + .../res/drawable/white_round_corner_bg.xml | 6 + .../src/main/res/layout/common_toolbar.xml | 82 + .../res/layout/custom_dialog_two_layout.xml | 53 + .../res/layout/custom_dialog_two_layout2.xml | 75 + .../src/main/res/layout/custom_dic_popup.xml | 15 + .../res/layout/custom_part_shadow_popup.xml | 10 + .../res/layout/dialog_download_layout.xml | 39 + .../src/main/res/layout/dialog_phone.xml | 57 + .../main/res/layout/dialog_photo_select.xml | 53 + mylibrary/src/main/res/layout/empty.xml | 40 + mylibrary/src/main/res/layout/empty_pic.xml | 41 + .../src/main/res/layout/gv_filter_image.xml | 46 + .../src/main/res/layout/item_car_select.xml | 71 + .../src/main/res/layout/item_dic_select.xml | 13 + .../src/main/res/layout/item_node_select.xml | 60 + mylibrary/src/main/res/layout/item_select.xml | 12 + .../main/res/layout/my_confim_popup_input.xml | 75 + .../main/res/layout/my_confim_popup_tip.xml | 70 + .../main/res/layout/my_confim_popup_unus.xml | 72 + .../layout/upush_bar_image_notification.xml | 13 + .../main/res/layout/upush_notification.xml | 67 + mylibrary/src/main/res/layout/view_node.xml | 68 + .../src/main/res/layout/view_slide_bar.xml | 182 ++ mylibrary/src/main/res/values/attrs.xml | 211 ++ mylibrary/src/main/res/values/colors.xml | 30 + mylibrary/src/main/res/values/dimens.xml | 26 + mylibrary/src/main/res/values/ids.xml | 6 + mylibrary/src/main/res/values/strings.xml | 7 + mylibrary/src/main/res/values/styles.xml | 55 + .../com/dahe/mylibrary/ExampleUnitTest.kt | 17 + 172 files changed, 16740 insertions(+) create mode 100644 mylibrary/.gitignore create mode 100644 mylibrary/build.gradle create mode 100644 mylibrary/consumer-rules.pro create mode 100644 mylibrary/proguard-rules.pro create mode 100644 mylibrary/src/androidTest/java/com/dahe/mylibrary/ExampleInstrumentedTest.kt create mode 100644 mylibrary/src/main/AndroidManifest.xml create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/CommonBaseLibrary.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/adapter/CarAdapter.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/adapter/CenterSimAdapter.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/adapter/GridImageAdapter.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/adapter/NodeAdapter.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/adapter/SelectDicAdapter.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/base/BaseActivity.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/base/BaseFragment.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/bean/CarBean.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/bean/DictBean.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/bean/NodeBean.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/bean/StateBean.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/bean/TipsBean.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/bean/VersionBean.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/callback/OnItemLongClickListener.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/callback/RefreshCallBack.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CarSelPopupView.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CenterPopupView.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CustomDicPopView.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CustomPartShadowPopupView.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/cuspop/InputPopupView.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/cuspop/NodePopupView.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/cuspop/TextPopupTipsView.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/cuspop/TextPopupView.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/dialog/DialogPhotoSelect.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/dialog/MyBaseDialog.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/dialog/VersionDialog.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/glide/AppGlideModule.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/glide/UnsafeOkHttpClient.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/net/CommonResponseBean.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/net/ErrorResponse.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/net/FileInterceptor.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/net/GsonResponseBodyConverter.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/net/JsonInterceptor.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/net/JsonUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/net/PagerBean.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/net/PagingBean.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/net/ResponseConverterFactory.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/net/ResultException.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/recycleviewswipe/GridSpacingItemDecoration.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/recycleviewswipe/MyDecoration.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/recycleviewswipe/RecycleViewDivider.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/ActivityUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/AppUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/BarUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/Base64Utils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/BaseSPUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/BaseUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/CNPinyinIndex.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/ConvertUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/CountDownTimerUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/CrashHandler.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/FileUtil.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/ImageLoader.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/LocationUtil.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/MD5Utils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/MemoryConstants.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/PatternUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/PhoneFormatCheckUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/SelectPhotoUtils4.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/SelectPhotoUtils5.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/SelectPhotoUtils6.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/ShellUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/SmsTimeUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/StatusBar.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/StatusBarCompatKitKat.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/StatusBarCompatLollipop.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/StringUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/TimeConstants.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/TimeUtil.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/TimingX.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/ToastUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/utils/VersionUtils.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/wapper/SelectSimAdapter.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/weight/AttachButton.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/weight/FullyGridLayoutManager.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/weight/GlideCircleWithBorder.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/weight/GlideEngine.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/weight/GridSectionAverageGapItemDecoration.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/weight/MovedImageButton.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/weight/MySlideBar.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/weight/SideBar.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/weight/SwitchView.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/weight/segmentcontrol/RadiusDrawable.java create mode 100644 mylibrary/src/main/java/com/dahe/mylibrary/weight/segmentcontrol/SegmentControl.java create mode 100644 mylibrary/src/main/res/anim/anim_bottom_in.xml create mode 100644 mylibrary/src/main/res/anim/anim_bottom_out.xml create mode 100644 mylibrary/src/main/res/color/select_text_color.xml create mode 100644 mylibrary/src/main/res/drawable-hdpi/left.png create mode 100644 mylibrary/src/main/res/drawable-xhdpi/black_back.png create mode 100644 mylibrary/src/main/res/drawable-xhdpi/fab_add.png create mode 100644 mylibrary/src/main/res/drawable-xhdpi/ic_add_image.png create mode 100644 mylibrary/src/main/res/drawable-xhdpi/icon_upload.png create mode 100644 mylibrary/src/main/res/drawable-xhdpi/left.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/cars.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/cha.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/check_nor.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/check_sel.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/diss.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/empty.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/error.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/fab_add.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/icon_refuse.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/id_select.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/id_select_loading.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/id_select_z.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/left.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/message.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/ok.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/update_head.png create mode 100644 mylibrary/src/main/res/drawable-xxhdpi/version_top_bg.png create mode 100644 mylibrary/src/main/res/drawable-xxxhdpi/left.png create mode 100644 mylibrary/src/main/res/drawable-xxxhdpi/version_top_bg.png create mode 100644 mylibrary/src/main/res/drawable/bnav_shape_du.xml create mode 100644 mylibrary/src/main/res/drawable/bnav_tab_background.xml create mode 100644 mylibrary/src/main/res/drawable/loading.xml create mode 100644 mylibrary/src/main/res/drawable/select_check_node.xml create mode 100644 mylibrary/src/main/res/drawable/select_sim_text.xml create mode 100644 mylibrary/src/main/res/drawable/select_slide_title.xml create mode 100644 mylibrary/src/main/res/drawable/select_text_c.xml create mode 100644 mylibrary/src/main/res/drawable/shadow_bg.9.png create mode 100644 mylibrary/src/main/res/drawable/shape_bg8.xml create mode 100644 mylibrary/src/main/res/drawable/shape_bind_phone_background.xml create mode 100644 mylibrary/src/main/res/drawable/shape_blue_bg10.xml create mode 100644 mylibrary/src/main/res/drawable/shape_blue_bg25.xml create mode 100644 mylibrary/src/main/res/drawable/shape_blue_bg4.xml create mode 100644 mylibrary/src/main/res/drawable/shape_blue_bg8.xml create mode 100644 mylibrary/src/main/res/drawable/shape_bottom_bgw16.xml create mode 100644 mylibrary/src/main/res/drawable/shape_gray_bg10.xml create mode 100644 mylibrary/src/main/res/drawable/shape_gray_bg25.xml create mode 100644 mylibrary/src/main/res/drawable/shape_gray_bg4.xml create mode 100644 mylibrary/src/main/res/drawable/shape_log_btn_bg22.xml create mode 100644 mylibrary/src/main/res/drawable/shape_message.xml create mode 100644 mylibrary/src/main/res/drawable/shape_text_4_blue.xml create mode 100644 mylibrary/src/main/res/drawable/shape_text_4_nor.xml create mode 100644 mylibrary/src/main/res/drawable/shape_view_v.xml create mode 100644 mylibrary/src/main/res/drawable/white_round_corner_bg.xml create mode 100644 mylibrary/src/main/res/layout/common_toolbar.xml create mode 100644 mylibrary/src/main/res/layout/custom_dialog_two_layout.xml create mode 100644 mylibrary/src/main/res/layout/custom_dialog_two_layout2.xml create mode 100644 mylibrary/src/main/res/layout/custom_dic_popup.xml create mode 100644 mylibrary/src/main/res/layout/custom_part_shadow_popup.xml create mode 100644 mylibrary/src/main/res/layout/dialog_download_layout.xml create mode 100644 mylibrary/src/main/res/layout/dialog_phone.xml create mode 100644 mylibrary/src/main/res/layout/dialog_photo_select.xml create mode 100644 mylibrary/src/main/res/layout/empty.xml create mode 100644 mylibrary/src/main/res/layout/empty_pic.xml create mode 100644 mylibrary/src/main/res/layout/gv_filter_image.xml create mode 100644 mylibrary/src/main/res/layout/item_car_select.xml create mode 100644 mylibrary/src/main/res/layout/item_dic_select.xml create mode 100644 mylibrary/src/main/res/layout/item_node_select.xml create mode 100644 mylibrary/src/main/res/layout/item_select.xml create mode 100644 mylibrary/src/main/res/layout/my_confim_popup_input.xml create mode 100644 mylibrary/src/main/res/layout/my_confim_popup_tip.xml create mode 100644 mylibrary/src/main/res/layout/my_confim_popup_unus.xml create mode 100644 mylibrary/src/main/res/layout/upush_bar_image_notification.xml create mode 100644 mylibrary/src/main/res/layout/upush_notification.xml create mode 100644 mylibrary/src/main/res/layout/view_node.xml create mode 100644 mylibrary/src/main/res/layout/view_slide_bar.xml create mode 100644 mylibrary/src/main/res/values/attrs.xml create mode 100644 mylibrary/src/main/res/values/colors.xml create mode 100644 mylibrary/src/main/res/values/dimens.xml create mode 100644 mylibrary/src/main/res/values/ids.xml create mode 100644 mylibrary/src/main/res/values/strings.xml create mode 100644 mylibrary/src/main/res/values/styles.xml create mode 100644 mylibrary/src/test/java/com/dahe/mylibrary/ExampleUnitTest.kt diff --git a/mylibrary/.gitignore b/mylibrary/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/mylibrary/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/mylibrary/build.gradle b/mylibrary/build.gradle new file mode 100644 index 0000000..e33e607 --- /dev/null +++ b/mylibrary/build.gradle @@ -0,0 +1,99 @@ +plugins { + id 'com.android.library' + id 'kotlin-android' +// id 'com.jakewharton.butterknife' +} + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } +} + +dependencies { + + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation 'androidx.core:core-ktx:1.3.1' + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + testImplementation 'junit:junit:4.+' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + + +// api rootProject.ext.dependencies["butterknife"] +// annotationProcessor rootProject.ext.dependencies["butterknife-compiler"] + api rootProject.ext.dependencies["gson"] + api rootProject.ext.dependencies["glide"] + annotationProcessor rootProject.ext.dependencies["glide-compiler"] + api rootProject.ext.dependencies["agentweb"] + api rootProject.ext.dependencies["Banner"] + api rootProject.ext.dependencies["RefreshLayout"] + api rootProject.ext.dependencies["rxjava"] + api rootProject.ext.dependencies["rxandroid"] + api rootProject.ext.dependencies["retrofit"] + api rootProject.ext.dependencies["converter-gson"] + api rootProject.ext.dependencies["adapter-rxjava2"] + api rootProject.ext.dependencies["okhttp"] + api rootProject.ext.dependencies["logging-interceptor"] + api rootProject.ext.dependencies["recyclerview"] + api rootProject.ext.dependencies["AutoSize"] + api rootProject.ext.dependencies["statusbaruitl"] + api rootProject.ext.dependencies["BaseRecyclerViewAdapterHelper"] + api rootProject.ext.dependencies["PhotoPicker"] + api rootProject.ext.dependencies["PickerView"] + api rootProject.ext.dependencies["Xpopup"] + api rootProject.ext.dependencies["Countdownview"] + api rootProject.ext.dependencies["CheckVersionLib"] + api rootProject.ext.dependencies["Bugly"] + api rootProject.ext.dependencies["Zxing"] + api rootProject.ext.dependencies["Multidex"] + api rootProject.ext.dependencies["FlycoTabLayout"] + api rootProject.ext.dependencies["NiceDialog"] + api rootProject.ext.dependencies["MagicIndicator"] + api rootProject.ext.dependencies["glide-okhttps"] + api 'pub.devrel:easypermissions:3.0.0' + + //友盟基础库(必须) +// api 'com.umeng.umsdk:common:9.4.4' +// api 'com.umeng.umsdk:asms:1.4.1' + + //友盟推送库 +// api 'com.umeng.umsdk:push:6.4.5' +// +// api 'com.umeng.umsdk:huawei-umengaccs:1.3.5' +// api 'com.huawei.hms:push:5.3.0.304' +// +// +// +// api('com.aliyun.ams:alicloud-android-hotfix:3.3.0') { +// exclude(module: 'alicloud-android-ut') +// exclude(module: 'alicloud-android-utdid') +// exclude(module: 'alicloud-android-utils') +// } +// api 'com.aliyun.dpa:oss-android-sdk:2.9.5' + +} diff --git a/mylibrary/consumer-rules.pro b/mylibrary/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/mylibrary/proguard-rules.pro b/mylibrary/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/mylibrary/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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 \ No newline at end of file diff --git a/mylibrary/src/androidTest/java/com/dahe/mylibrary/ExampleInstrumentedTest.kt b/mylibrary/src/androidTest/java/com/dahe/mylibrary/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..c51c36c --- /dev/null +++ b/mylibrary/src/androidTest/java/com/dahe/mylibrary/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.dahe.mylibrary + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.dahe.mylibrary.test", appContext.packageName) + } +} \ No newline at end of file diff --git a/mylibrary/src/main/AndroidManifest.xml b/mylibrary/src/main/AndroidManifest.xml new file mode 100644 index 0000000..2f43892 --- /dev/null +++ b/mylibrary/src/main/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/CommonBaseLibrary.java b/mylibrary/src/main/java/com/dahe/mylibrary/CommonBaseLibrary.java new file mode 100644 index 0000000..8354e02 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/CommonBaseLibrary.java @@ -0,0 +1,137 @@ +package com.dahe.mylibrary; + +import android.app.Activity; +import android.app.Application; +import android.content.Context; +import android.os.Bundle; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.scwang.smartrefresh.layout.SmartRefreshLayout; +import com.scwang.smartrefresh.layout.api.DefaultRefreshFooterCreator; +import com.scwang.smartrefresh.layout.api.DefaultRefreshHeaderCreator; +import com.scwang.smartrefresh.layout.api.RefreshFooter; +import com.scwang.smartrefresh.layout.api.RefreshHeader; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.footer.ClassicsFooter; +import com.scwang.smartrefresh.layout.header.ClassicsHeader; + +import java.lang.ref.WeakReference; +import java.util.LinkedList; +import java.util.List; + +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; + +/** + * Created by Administrator on 2018/7/15 0015. + */ + +public class CommonBaseLibrary { + public volatile static CommonBaseLibrary mInstance = null; + private static Application mApplication = null; + public static WeakReference topActivity; + public static List activityList = new LinkedList<>(); + private static Retrofit mRetrofit; + + static { + SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() { + @Override + public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) { + return new ClassicsHeader(context); + } + }); + SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() { + @Override + public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) { + return new ClassicsFooter(context); + } + }); + } + + public CommonBaseLibrary() { + } + + public static CommonBaseLibrary getInstance() { + if (null == mInstance) { + synchronized (CommonBaseLibrary.class) { + if (null == mInstance) { + mInstance = new CommonBaseLibrary(); + } + } + } + return mInstance; + } + + public CommonBaseLibrary init(Application application, String baseUrl) { + mApplication = application; + application.registerActivityLifecycleCallbacks(mCallbacks); + Gson gson = new GsonBuilder().setDateFormat("yyy-MM-dd HH:mm:ss").create(); + mRetrofit = new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create(gson)) + .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) + .build(); + +// .addConverterFactory(GsonConverterFactory.create(gson)) + return this; + } + + + + public static Application getApplication() { + return mApplication; + } + + public static Retrofit getRetrofit() { + if (null == mRetrofit) + throw new NullPointerException("please call CommonBaseLibrary.getInstance().init() first in application!"); + return mRetrofit; + + } + + private static Application.ActivityLifecycleCallbacks mCallbacks = new Application.ActivityLifecycleCallbacks() { + @Override + public void onActivityCreated(Activity activity, Bundle bundle) { + activityList.add(activity); + setTopActivityWeakRef(activity); + } + + @Override + public void onActivityStarted(Activity activity) { + setTopActivityWeakRef(activity); + } + + @Override + public void onActivityResumed(Activity activity) { + setTopActivityWeakRef(activity); + } + + @Override + public void onActivityPaused(Activity activity) { + + } + + @Override + public void onActivityStopped(Activity activity) { + + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { + + } + + @Override + public void onActivityDestroyed(Activity activity) { + activityList.remove(activity); + } + }; + + private static void setTopActivityWeakRef(Activity activity) { + if (topActivity == null || !activity.equals(topActivity.get())) { + topActivity = new WeakReference<>(activity); + } + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/adapter/CarAdapter.java b/mylibrary/src/main/java/com/dahe/mylibrary/adapter/CarAdapter.java new file mode 100644 index 0000000..0d2df13 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/adapter/CarAdapter.java @@ -0,0 +1,31 @@ +package com.dahe.mylibrary.adapter; + +import android.widget.CheckBox; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.bean.CarBean; +import com.dahe.mylibrary.bean.NodeBean; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class CarAdapter extends BaseQuickAdapter { + + public CarAdapter(int layoutResId, @Nullable List data) { + super(R.layout.item_car_select, data); + } + + @Override + protected void convert(@NotNull BaseViewHolder helper, CarBean item) { + helper.setText(R.id.tv_title, item.getVehicle()) + .setText(R.id.tv_lxr, "司机信息:"+item.getDriverName() + " " + item.getDriverPhone()) + .setText(R.id.tv_zz, "载重(Kg):"+item.getApprovedLoad()) + .setText(R.id.tv_ckg, "长宽高(毫米):"+item.getOutlineLong()+"*"+item.getOutlineWide()+"*"+item.getOutlineHigh()); + CheckBox cb = helper.getView(R.id.cb); + cb.setChecked(item.isSelect()); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/adapter/CenterSimAdapter.java b/mylibrary/src/main/java/com/dahe/mylibrary/adapter/CenterSimAdapter.java new file mode 100644 index 0000000..27f52e7 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/adapter/CenterSimAdapter.java @@ -0,0 +1,41 @@ +package com.dahe.mylibrary.adapter; + +import android.widget.TextView; + +import androidx.annotation.Nullable; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.bean.StateBean; + +import java.util.List; + +public class CenterSimAdapter extends BaseQuickAdapter { + private StateBean selectString=null; + + + public CenterSimAdapter(int layoutResId, @Nullable List data, StateBean selectString) { + super(R.layout.item_select, data); + this.selectString = selectString; + } + + @Override + protected void convert(BaseViewHolder helper, StateBean item) { + helper.setText(R.id.tv_content,item.getDictLabel()); + TextView tv = helper.getView(R.id.tv_content); + if (selectString!=null&&item.getDictValue()!=null){ + if (item.getDictValue().equals(selectString.getDictValue())){ + tv.setSelected(true); + }else{ + tv.setSelected(false); + } + } + + + } + + public void setSelect(StateBean selectString){ + this.selectString = selectString; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/adapter/GridImageAdapter.java b/mylibrary/src/main/java/com/dahe/mylibrary/adapter/GridImageAdapter.java new file mode 100644 index 0000000..d0fdb18 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/adapter/GridImageAdapter.java @@ -0,0 +1,272 @@ +package com.dahe.mylibrary.adapter; + +import android.content.Context; +import android.net.Uri; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.load.resource.bitmap.CenterCrop; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.callback.OnItemLongClickListener; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.luck.picture.lib.listener.OnItemClickListener; +import com.luck.picture.lib.tools.DateUtils; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + + +/** + * @author:luck + * @date:2016-7-27 23:02 + * @describe:GridImageAdapter + */ +public class GridImageAdapter extends + RecyclerView.Adapter { + public static final String TAG = "PictureSelector"; + public static final int TYPE_CAMERA = 1; + public static final int TYPE_PICTURE = 2; + public boolean IS_ONLY_SHOW = false; + private final Context ctx; + private LayoutInflater mInflater; + private List list = new ArrayList<>(); + private int selectMax = 9; + /** + * 点击添加图片跳转 + */ + private onAddPicClickListener mOnAddPicClickListener; + + public interface onAddPicClickListener { + void onAddPicClick(); + void onDelPicClick(int postion,LocalMedia localMedia); + } + + /** + * 删除 + */ + public void delete(int position) { + try { + + if (position != RecyclerView.NO_POSITION && list.size() > position) { + list.remove(position); + notifyItemRemoved(position); + notifyItemRangeChanged(position, list.size()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public GridImageAdapter(Context context, onAddPicClickListener mOnAddPicClickListener) { + this.ctx = context; + this.mInflater = LayoutInflater.from(context); + this.mOnAddPicClickListener = mOnAddPicClickListener; + } + + public void setSelectMax(int selectMax) { + this.selectMax = selectMax; + } + + public void setList(List list) { + this.list = list; + } + + public void setListNotif(List list) { + if (null!=list&&list.size()>0){ + this.list = list; + notifyDataSetChanged(); + } + } + + public List getData() { + return list == null ? new ArrayList<>() : list; + } + + public void remove(int position) { + if (list != null && position < list.size()) { + list.remove(position); + } + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + + ImageView mImg; + ImageView mIvDel; + TextView tvDuration; + + public ViewHolder(View view) { + super(view); + mImg = view.findViewById(R.id.fiv); + mIvDel = view.findViewById(R.id.iv_del); + tvDuration = view.findViewById(R.id.tv_duration); + } + } + + @Override + public int getItemCount() { + if (list.size() < selectMax&&!IS_ONLY_SHOW) { + return list.size() + 1; + } else { + return list.size(); + } + } + + @Override + public int getItemViewType(int position) { + if (isShowAddItem(position)) { + return TYPE_CAMERA; + } else { + return TYPE_PICTURE; + } + } + + /** + * 创建ViewHolder + */ + @Override + public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { + View view = mInflater.inflate(R.layout.gv_filter_image, viewGroup, false); + return new ViewHolder(view); + } + + private boolean isShowAddItem(int position) { + if (IS_ONLY_SHOW){ + return false; + } + int size = list.size(); + return position == size; + } + + public void setIsOnlyShow(boolean b){ + this.IS_ONLY_SHOW = b; + } + + /** + * 设置值 + */ + @Override + public void onBindViewHolder(final ViewHolder viewHolder, final int position) { + //少于8张,显示继续添加的图标 + if (getItemViewType(position) == TYPE_CAMERA) { + viewHolder.mImg.setImageResource(R.drawable.id_select_z); +// viewHolder.mImg.setImageResource(R.drawable.ic_add_image); + viewHolder.mImg.setOnClickListener(v -> mOnAddPicClickListener.onAddPicClick()); + viewHolder.mIvDel.setVisibility(View.INVISIBLE); + } else { + viewHolder.mIvDel.setVisibility(IS_ONLY_SHOW?View.GONE:View.VISIBLE); + viewHolder.mIvDel.setOnClickListener(view -> { + int index = viewHolder.getAbsoluteAdapterPosition(); + + // 这里有时会返回-1造成数据下标越界,具体可参考getAdapterPosition()源码, + // 通过源码分析应该是bindViewHolder()暂未绘制完成导致,知道原因的也可联系我~感谢 + if (index != RecyclerView.NO_POSITION && list.size() > index) { + mOnAddPicClickListener.onDelPicClick(index, list.get(index)); +// list.remove(index); +// notifyItemRemoved(index); +// notifyItemRangeChanged(index, list.size()); + } + }); + LocalMedia media = list.get(position); + if (media == null + || TextUtils.isEmpty(media.getPath())) { + return; + } + int chooseModel = media.getChooseModel(); + String path; + if (media.isCut() && !media.isCompressed()) { + // 裁剪过 + path = media.getCutPath(); + } else if (media.isCompressed() || (media.isCut() && media.isCompressed())) { + // 压缩过,或者裁剪同时压缩过,以最终压缩过图片为准 + path = media.getCompressPath(); + } else { + // 原图 + path = media.getPath(); + } + + Log.i(TAG, "原图地址::" + media.getPath()); + + if (media.isCut()) { + Log.i(TAG, "裁剪地址::" + media.getCutPath()); + } + if (media.isCompressed()) { + Log.i(TAG, "压缩地址::" + media.getCompressPath()); + Log.i(TAG, "压缩后文件大小::" + new File(media.getCompressPath()).length() / 1024 + "k"); + } + if (!TextUtils.isEmpty(media.getAndroidQToPath())) { + Log.i(TAG, "Android Q特有地址::" + media.getAndroidQToPath()); + } + if (media.isOriginal()) { + Log.i(TAG, "是否开启原图功能::" + true); + Log.i(TAG, "开启原图功能后地址::" + media.getOriginalPath()); + } + + long duration = media.getDuration(); + viewHolder.tvDuration.setVisibility(PictureMimeType.isHasVideo(media.getMimeType()) + ? View.VISIBLE : View.GONE); + if (chooseModel == PictureMimeType.ofAudio()) { + viewHolder.tvDuration.setVisibility(View.VISIBLE); + viewHolder.tvDuration.setCompoundDrawablesRelativeWithIntrinsicBounds + (R.drawable.picture_icon_audio, 0, 0, 0); + + } else { + viewHolder.tvDuration.setCompoundDrawablesRelativeWithIntrinsicBounds + (R.drawable.picture_icon_video, 0, 0, 0); + } + viewHolder.tvDuration.setText(DateUtils.formatDurationTime(duration)); + if (chooseModel == PictureMimeType.ofAudio()) { + viewHolder.mImg.setImageResource(R.drawable.picture_audio_placeholder); + } else { + RequestOptions requestOptions = RequestOptions.fitCenterTransform().transform(new CenterCrop(), new RoundedCorners(5)); + Glide.with(ctx) + .load(PictureMimeType.isContent(path) && !media.isCut() && !media.isCompressed() ? Uri.parse(path) + : path) + .centerCrop() + .apply(requestOptions)//圆角半径 + .placeholder(R.drawable.id_select_loading) + .diskCacheStrategy(DiskCacheStrategy.ALL) + .into(viewHolder.mImg); + } + //itemView 的点击事件 + if (mItemClickListener != null) { + viewHolder.itemView.setOnClickListener(v -> { + int adapterPosition = viewHolder.getAdapterPosition(); + mItemClickListener.onItemClick(v, adapterPosition); + }); + } + + if (mItemLongClickListener != null) { + viewHolder.itemView.setOnLongClickListener(v -> { + int adapterPosition = viewHolder.getAdapterPosition(); + mItemLongClickListener.onItemLongClick(viewHolder, adapterPosition, v); + return true; + }); + } + } + } + + private OnItemClickListener mItemClickListener; + + public void setOnItemClickListener(OnItemClickListener l) { + this.mItemClickListener = l; + } + + private OnItemLongClickListener mItemLongClickListener; + + public void setItemLongClickListener(OnItemLongClickListener l) { + this.mItemLongClickListener = l; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/adapter/NodeAdapter.java b/mylibrary/src/main/java/com/dahe/mylibrary/adapter/NodeAdapter.java new file mode 100644 index 0000000..b4da2e0 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/adapter/NodeAdapter.java @@ -0,0 +1,30 @@ +package com.dahe.mylibrary.adapter; + +import android.widget.CheckBox; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.bean.NodeBean; +import com.dahe.mylibrary.utils.StringUtils; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class NodeAdapter extends BaseQuickAdapter { + + public NodeAdapter(int layoutResId, @Nullable List data) { + super(R.layout.item_node_select, data); + } + + @Override + protected void convert(@NotNull BaseViewHolder helper, NodeBean item) { + helper.setText(R.id.tv_title, item.getNode()) + .setText(R.id.tv_lxr, StringUtils.isEmpty(item.getDocking())?"":item.getDocking() + " " + (StringUtils.isEmpty(item.getDockingPhone())?"":item.getDockingPhone())) + .setText(R.id.tv_addres, item.getFreighter()); + CheckBox cb = helper.getView(R.id.cb); + cb.setChecked("1".equals(item.isSelect())?true:false); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/adapter/SelectDicAdapter.java b/mylibrary/src/main/java/com/dahe/mylibrary/adapter/SelectDicAdapter.java new file mode 100644 index 0000000..06159d9 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/adapter/SelectDicAdapter.java @@ -0,0 +1,38 @@ +package com.dahe.mylibrary.adapter; + +import androidx.annotation.Nullable; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.bean.DictBean; +import com.dahe.mylibrary.bean.StateBean; + +import java.util.List; + + +public class SelectDicAdapter extends BaseQuickAdapter { + private int selectPos = -1; + + + public SelectDicAdapter(int layoutResId, @Nullable List data, int selectPos) { + super(R.layout.item_dic_select, data); + this.selectPos = selectPos; + } + + @Override + protected void convert(BaseViewHolder helper, StateBean item) { + helper.setText(R.id.tv_content,item.getDictLabel()); +// TextView tv = helper.getView(R.id.tv_content); +// if (item.equals(selectString)){ +// tv.setSelected(true); +// }else{ +// tv.setSelected(false); +// } + + } + + public void setSelect(int selectString){ + this.selectPos = selectString; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/base/BaseActivity.java b/mylibrary/src/main/java/com/dahe/mylibrary/base/BaseActivity.java new file mode 100644 index 0000000..65a2fc1 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/base/BaseActivity.java @@ -0,0 +1,250 @@ +package com.dahe.mylibrary.base; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.View; +import android.view.ViewGroup; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import androidx.annotation.ColorRes; +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.core.content.ContextCompat; + +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.callback.RefreshCallBack; +import com.dahe.mylibrary.utils.BarUtils; +import com.dahe.mylibrary.utils.ConvertUtils; +import com.dahe.mylibrary.utils.StatusBar; +import com.dahe.mylibrary.utils.ToastUtils; +import com.scwang.smartrefresh.layout.SmartRefreshLayout; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.constant.RefreshState; +import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener; + +import qiu.niorgai.StatusBarCompat; + + +public abstract class BaseActivity extends AppCompatActivity { + protected Context mContext; + protected final int DEFAULT_STATUS_BAR_ALPHA = 0; + private static final String TAG = "BaseActivity"; + protected Toolbar mToolbar; + protected int mRefreshPage = 1; + protected int mRefreshCount = 15; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(getLayout()); + mContext = this; + setStatusBarColor(R.color.colorPrimaryDark); + initView(savedInstanceState); + initDate(); + } + + /** + * 标题栏的颜色 文字白色 + */ + public void setStatusBarCancelLightColor() { + StatusBar.cancelLightStatusBar(this); + } + + + /** + * 设置沉浸式标题栏 标题栏的颜色 + */ + public void setStatusBarColor(int color) { + StatusBarCompat.setStatusBarColor(this, ContextCompat.getColor(mContext, color), DEFAULT_STATUS_BAR_ALPHA); + StatusBar.changeToLightStatusBar(this); //黑色 下边白色 +// StatusBar.cancelLightStatusBar(this); + } + + /** + * 设置沉浸式标题栏 标题栏的颜色 + */ + public void setStatusBarColor() { +// StatusBarCompat.setStatusBarColor(this, ContextCompat.getColor(mContext, color), DEFAULT_STATUS_BAR_ALPHA); +// StatusBar.changeToLightStatusBar(this); //黑色 下边白色 + StatusBar.cancelLightStatusBar(this); + } + + /** + * 设置沉浸式标题栏 里面是Fragment + */ + public void setStatusBarColorInFragment() { + StatusBarCompat.translucentStatusBar(this); + } + + /** + * 设置透明沉浸式标题栏 + */ + public void setStatusBarColorToLight() { + StatusBar.translucentStatusBar(this, false); + StatusBar.changeToLightStatusBar(this); + } + + /** + * 设置标题 + */ + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + protected void setTitleBar(String title, View.OnClickListener listener) { + mToolbar = (Toolbar) findViewById(R.id.common_toolbar); + if (!TextUtils.isEmpty(title)) + ((TextView) findViewById(R.id.common_toolBar_title)).setText(title); + mToolbar.setNavigationIcon(R.drawable.left); + mToolbar.setNavigationOnClickListener(listener); + } + + /** + * 设置标题 + */ + + protected void setTitleBar(String title) { + mToolbar = (Toolbar) findViewById(R.id.common_toolbar); + if (!TextUtils.isEmpty(title)) + ((TextView) findViewById(R.id.common_toolBar_title)).setText(title); + } + + /** + * 显示右边标题 + * + * @param title + * @param listener + * @param isVisible + * @param right + */ + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + protected void setTitleBar(String title, View.OnClickListener listener, boolean isVisible, String right, View.OnClickListener rightListener) { + mToolbar = (Toolbar) findViewById(R.id.common_toolbar); + if (!TextUtils.isEmpty(title)) + ((TextView) findViewById(R.id.common_toolBar_title)).setText(title); + TextView mTextRight = (TextView) findViewById(R.id.common_toolBar_text_right); + if (isVisible) { + mTextRight.setVisibility(View.VISIBLE); + mTextRight.setText(right); + mTextRight.setOnClickListener(rightListener); + } + mToolbar.setNavigationIcon(R.drawable.left); + mToolbar.setNavigationOnClickListener(listener); + } + + /** + * 设置距离顶部距离 + */ + protected void setStatusHeightParams(View llContent) { + RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + closeLayoutParams.topMargin = ConvertUtils.dp2px(8) + BarUtils.getStatusBarHeight(); +// closeLayoutParams.topMargin = BarUtils.getStatusBarHeight(); + llContent.setLayoutParams(closeLayoutParams); + } + + protected abstract int getLayout(); + + protected abstract void initView(Bundle savedInstanceState); + + protected abstract void initDate(); + + protected void showToast(Object message) { + ToastUtils.showToast(this, message instanceof String ? message + "" : getResources().getString((int) message)); + } + + protected void canCelToast(){ + ToastUtils.cancelToast(); + } + + +// protected void showToast(Object message,int time) { +// ToastUtils.showToast(this, message instanceof String ? message + "" : getResources().getString((int) message),time); +// } + + @Override + protected void onDestroy() { + super.onDestroy(); + } + + + /** + * 设置刷新控件 + * + * @param refreshLayout + * @param callBack 访问网络回调 + */ + protected void setRefresh(final SmartRefreshLayout refreshLayout, final RefreshCallBack callBack) { + refreshLayout.setEnableOverScrollDrag(true) + .setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + mRefreshPage++; + callBack.getRefreshDate(2, mRefreshPage, mRefreshCount); + } + + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + mRefreshPage = 1; + callBack.getRefreshDate(1, mRefreshPage, mRefreshCount); + } + }); + } + + /** + * 网络访问完成 刷新控件 + * + * @param refreshLayout + * @param isLoadMore false禁用下拉加载更多 + */ + protected void setFinishRefresh(final SmartRefreshLayout refreshLayout, boolean isLoadMore) { + if (refreshLayout != null && refreshLayout.getState() == RefreshState.Refreshing) + refreshLayout.finishRefresh(); + else if (refreshLayout != null && refreshLayout.getState() == RefreshState.Loading) + refreshLayout.finishLoadMore(); + if (!isLoadMore){ + refreshLayout.finishLoadMore(); //加载完成 + refreshLayout.finishLoadMoreWithNoMoreData(); //全部加载完成,没有数据了调用此方法 + } +// refreshLayout.setEnableLoadMore(isLoadMore); + } + + public void onClick(View view){ + + } + + + /** + * 获取Drawable + * + * @param id + * @return + */ + protected Drawable getDrawableV4(@DrawableRes int id) { + return ContextCompat.getDrawable(this, id); + } + + /** + * 获取Color + * + * @param id + * @return + */ + protected int getColorV4(@ColorRes int id) { + return ContextCompat.getColor(this, id); + } + + @Override + public void onResume() { + super.onResume(); + } + + @Override + public void onPause() { + super.onPause(); + } + + +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/base/BaseFragment.java b/mylibrary/src/main/java/com/dahe/mylibrary/base/BaseFragment.java new file mode 100644 index 0000000..0e67b39 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/base/BaseFragment.java @@ -0,0 +1,321 @@ +package com.dahe.mylibrary.base; + + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; + +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.callback.RefreshCallBack; +import com.dahe.mylibrary.utils.StatusBar; +import com.dahe.mylibrary.utils.ToastUtils; +import com.scwang.smartrefresh.layout.SmartRefreshLayout; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.constant.RefreshState; +import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener; + +import qiu.niorgai.StatusBarCompat; + +/** + *

+ * Fragment基类,封装了懒加载的实现 + *

+ * 1、Viewpager + Fragment情况下,fragment的生命周期因Viewpager的缓存机制而失去了具体意义 + * 该抽象类自定义一个新的回调方法,当fragment可见状态改变时会触发的回调方法 + * + * @see #onFragmentVisibleChange(boolean) + * @see #onFragmentFirstVisible() + */ +public abstract class BaseFragment extends Fragment { + private boolean isFragmentVisible; + private boolean isReuseView; + private boolean isFirstVisible; + private boolean isPause; + private View rootView; + private static final String TAG = "BaseFragment"; + protected Context mContext; + protected int mRefreshPage = 1; + protected int mRefreshCount = 20; + protected Toolbar mToolbar; + protected final int DEFAULT_STATUS_BAR_ALPHA = 0; + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + Log.i(TAG, "onViewCreated: " + (rootView == null) + "---getUserVisibleHint()" + getUserVisibleHint() + "---isFirstVisible" + isFirstVisible); + //如果setUserVisibleHint()在rootView创建前调用时,那么 + //就等到rootView创建完后才回调onFragmentVisibleChange(true) + //保证onFragmentVisibleChange()的回调发生在rootView创建完成之后,以便支持ui操作 + if (rootView == null) { + rootView = view; + if (getUserVisibleHint()) { + if (isFirstVisible) { + onFragmentFirstVisible(); + isFirstVisible = false; + } + + onFragmentVisibleChange(isFirstVisible); + isFragmentVisible = true; + } + } + super.onViewCreated(isReuseView && rootView != null ? rootView : view, savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + if (getContentViewLayoutID() != 0) { + mContext = getActivity(); + return inflater.inflate(getContentViewLayoutID(), container, false); + } else { + return super.onCreateView(inflater, container, savedInstanceState); + } + } + + + protected abstract int getContentViewLayoutID(); + + + /** + * 标题栏的颜色 文字白色 + */ + public void setStatusBarCancelLightColor() { + StatusBar.cancelLightStatusBar(getActivity()); + } + + /** + * 设置沉浸式标题栏 标题栏的颜色 + */ + public void setStatusBarColor(int color) { + StatusBarCompat.setStatusBarColor(getActivity(), ContextCompat.getColor(mContext, color), DEFAULT_STATUS_BAR_ALPHA); + StatusBar.changeToLightStatusBar(getActivity()); + } + + /** + * 设置沉浸式标题栏 里面是Fragment + */ + public void setStatusBarColorInFragment() { + StatusBarCompat.translucentStatusBar(getActivity()); + } + + public void setStatusBarColorToLight() { + StatusBar.translucentStatusBar(getActivity(), true); + StatusBar.changeToLightStatusBar(getActivity()); + } + + @Override + public void onDestroy() { + initVariable(); + super.onDestroy(); + } + + + protected void showToast(Object message) { + ToastUtils.showToast(mContext, message instanceof String ? message + "" : getResources().getString((int) message)); + } + + /** + * 设置刷新控件 + * + * @param refreshLayout + * @param callBack 访问网络回调 + */ + protected void setRefresh(final SmartRefreshLayout refreshLayout, final RefreshCallBack callBack) { + refreshLayout.setEnableOverScrollDrag(true) + .setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + mRefreshPage++; + callBack.getRefreshDate(2, mRefreshPage, mRefreshCount); + } + + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + mRefreshPage = 1; + callBack.getRefreshDate(1, mRefreshPage, mRefreshCount); + } + }); + } + + /** + * 网络访问完成 刷新控件 + * + * @param refreshLayout + * @param isLoadMore false禁用下拉加载更多 + */ + protected void setFinishRefresh(final SmartRefreshLayout refreshLayout, boolean isLoadMore) { + if (refreshLayout.getState() == RefreshState.Refreshing) + refreshLayout.finishRefresh(); + else if (refreshLayout.getState() == RefreshState.Loading) + refreshLayout.finishLoadMore(); + if (!isLoadMore){ + refreshLayout.finishLoadMore(); //加载完成 + refreshLayout.finishLoadMoreWithNoMoreData(); //全部加载完成,没有数据了调用此方法 + } +// refreshLayout.setEnableLoadMore(isLoadMore); + } + + /** + * 设置标题 + */ + + protected void setTitleBar(String title, View.OnClickListener listener) { + mToolbar = (Toolbar) rootView.findViewById(R.id.common_toolbar); + if (!TextUtils.isEmpty(title)) + ((TextView) rootView.findViewById(R.id.common_toolBar_title)).setText(title); + mToolbar.setNavigationIcon(R.drawable.black_back); + mToolbar.setNavigationOnClickListener(listener); + } + + /** + * 设置标题 + */ + + protected void setTitleBar(String title) { + mToolbar = (Toolbar) rootView.findViewById(R.id.common_toolbar); + if (!TextUtils.isEmpty(title)) + ((TextView) rootView.findViewById(R.id.common_toolBar_title)).setText(title); + } + + /** + * 设置标题 + */ + + protected void setTitleBar(String title, boolean isRight, View.OnClickListener listener) { + mToolbar = (Toolbar) rootView.findViewById(R.id.common_toolbar); + if (!TextUtils.isEmpty(title)) { + ((TextView) rootView.findViewById(R.id.common_toolBar_title)).setText(title); + ((RelativeLayout) rootView.findViewById(R.id.rlMessage)).setVisibility(isRight ? View.VISIBLE : View.GONE); + (rootView.findViewById(R.id.rlMessage)).setOnClickListener(listener); + } + } + + /** + * 设置标题 + */ + + protected void setTitleBar(String title, boolean isRight,String message, View.OnClickListener listener) { + mToolbar = (Toolbar) rootView.findViewById(R.id.common_toolbar); + if (!TextUtils.isEmpty(title)) { + ((TextView) rootView.findViewById(R.id.common_toolBar_title)).setText(title); + ((RelativeLayout) rootView.findViewById(R.id.rlMessage)).setVisibility(isRight ? View.VISIBLE : View.GONE); + ((TextView) rootView.findViewById(R.id.tvMessage)).setText(message); + (rootView.findViewById(R.id.rlMessage)).setOnClickListener(listener); + } + } + + /** + * 设置标题 + */ + + protected void setBadView(boolean isRight) { + if (null != ((TextView) rootView.findViewById(R.id.tvCount))) { + ((TextView) rootView.findViewById(R.id.tvCount)).setVisibility(isRight ? View.VISIBLE : View.GONE); + } + } + + protected void setCount(int count) { + if (count > 100) { + ((TextView) rootView.findViewById(R.id.tvCount)).setText("99··"); + } else { + ((TextView) rootView.findViewById(R.id.tvCount)).setText(count + ""); + } + + } + + + //setUserVisibleHint()在Fragment创建时会先被调用一次,传入isVisibleToUser = false + //如果当前Fragment可见,那么setUserVisibleHint()会再次被调用一次,传入isVisibleToUser = true + //如果Fragment从可见->不可见,那么setUserVisibleHint()也会被调用,传入isVisibleToUser = false + //总结:setUserVisibleHint()除了Fragment的可见状态发生变化时会被回调外,在new Fragment()时也会被回调 + @Override + public void setUserVisibleHint(boolean isVisibleToUser) { + Log.i(TAG, "isFirstVisible: " + isFirstVisible + "--isVisibleToUser" + isVisibleToUser + "--rootView == null" + (rootView == null)); + super.setUserVisibleHint(isVisibleToUser); + //setUserVisibleHint()有可能在fragment的生命周期外被调用 + if (rootView == null) { + return; + } + if (isFirstVisible && isVisibleToUser) { + onFragmentFirstVisible(); + isFirstVisible = false; + isFragmentVisible = true; + return; + } + if (isVisibleToUser) { + onFragmentVisibleChange(true); + isFragmentVisible = true; + return; + } + if (isFragmentVisible) { + isFragmentVisible = false; + onFragmentVisibleChange(false); + } + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + initVariable(); + } + + + private void initVariable() { + isFirstVisible = true; + isFragmentVisible = false; + isPause = false; + rootView = null; + isReuseView = true; + } + + @Override + public void onPause() { + isPause = true; + super.onPause(); + } + + @Override + public void onResume() { + if (isPause && getUserVisibleHint()) + onFragmentVisibleChange(true); + super.onResume(); + } + + /** + * @param isReuse + */ + protected void reuseView(boolean isReuse) { + isReuseView = isReuse; + } + + /** + * 去除setUserVisibleHint()多余的回调场景,保证只有当fragment可见状态发生变化时才回调 + * 回调时机在view创建完后,所以支持ui操作,解决在setUserVisibleHint()里进行ui操作有可能报null异常的问题 + *

+ * 可在该回调方法里进行一些ui显示与隐藏 + * + * @param isVisible true 不可见 -> 可见 + * false 可见 -> 不可见 + */ + protected abstract void onFragmentVisibleChange(boolean isVisible); + + /** + * 在fragment首次可见时回调,可用于加载数据,防止每次进入都重复加载数据 + */ + protected abstract void onFragmentFirstVisible(); + + protected boolean isFragmentVisible() { + return isFragmentVisible; + } +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/bean/CarBean.java b/mylibrary/src/main/java/com/dahe/mylibrary/bean/CarBean.java new file mode 100644 index 0000000..1691809 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/bean/CarBean.java @@ -0,0 +1,100 @@ +package com.dahe.mylibrary.bean; + +import java.io.Serializable; + +public class CarBean implements Serializable { + + +// private String approved_load; +// private String driver_name; +// private String current_load; +// private String car_number; +// private String outline_wide; +// private String outline_long; +// private String driver_phone; +// private Integer car_id; +// private String outline_high; + private boolean isSelect; + + private String vehicle; + private String carId; + private String outlineWide; + private String outlineHigh; + private String outlineLong; + private String approvedLoad; + private String driverName; + private String driverPhone; + + public String getVehicle() { + return vehicle; + } + + public void setVehicle(String vehicle) { + this.vehicle = vehicle; + } + + public String getCarId() { + return carId; + } + + public void setCarId(String carId) { + this.carId = carId; + } + + public String getOutlineWide() { + return outlineWide; + } + + public void setOutlineWide(String outlineWide) { + this.outlineWide = outlineWide; + } + + public String getOutlineHigh() { + return outlineHigh; + } + + public void setOutlineHigh(String outlineHigh) { + this.outlineHigh = outlineHigh; + } + + public String getOutlineLong() { + return outlineLong; + } + + public void setOutlineLong(String outlineLong) { + this.outlineLong = outlineLong; + } + + public String getApprovedLoad() { + return approvedLoad; + } + + public void setApprovedLoad(String approvedLoad) { + this.approvedLoad = approvedLoad; + } + + public String getDriverName() { + return driverName; + } + + public void setDriverName(String driverName) { + this.driverName = driverName; + } + + public String getDriverPhone() { + return driverPhone; + } + + public void setDriverPhone(String driverPhone) { + this.driverPhone = driverPhone; + } + + public boolean isSelect() { + return isSelect; + } + + public void setSelect(boolean select) { + isSelect = select; + } + +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/bean/DictBean.java b/mylibrary/src/main/java/com/dahe/mylibrary/bean/DictBean.java new file mode 100644 index 0000000..f8e9983 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/bean/DictBean.java @@ -0,0 +1,154 @@ +package com.dahe.mylibrary.bean; + +import java.io.Serializable; + +public class DictBean implements Serializable { + + + private String searchValue; + private String createBy; + private String createTime; + private String updateBy; + private String updateTime; + private String remark; + private String dictCode; + private String dictSort; + private String dictLabel; + private String dictValue; + private String dictType; + private String cssClass; + private String listClass; + private String isDefault; + private String status; + + public DictBean() { + + } + + public DictBean(String dictValue, String dictLabel) { + this.dictValue = dictValue; + this.dictLabel = dictLabel; + } + + public String getSearchValue() { + return searchValue; + } + + public void setSearchValue(String searchValue) { + this.searchValue = searchValue; + } + + public String getCreateBy() { + return createBy; + } + + public void setCreateBy(String createBy) { + this.createBy = createBy; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getUpdateBy() { + return updateBy; + } + + public void setUpdateBy(String updateBy) { + this.updateBy = updateBy; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + + public String getDictCode() { + return dictCode; + } + + public void setDictCode(String dictCode) { + this.dictCode = dictCode; + } + + public String getDictSort() { + return dictSort; + } + + public void setDictSort(String dictSort) { + this.dictSort = dictSort; + } + + public String getDictLabel() { + return dictLabel; + } + + public void setDictLabel(String dictLabel) { + this.dictLabel = dictLabel; + } + + public String getDictValue() { + return dictValue; + } + + public void setDictValue(String dictValue) { + this.dictValue = dictValue; + } + + public String getDictType() { + return dictType; + } + + public void setDictType(String dictType) { + this.dictType = dictType; + } + + public String getCssClass() { + return cssClass; + } + + public void setCssClass(String cssClass) { + this.cssClass = cssClass; + } + + public String getListClass() { + return listClass; + } + + public void setListClass(String listClass) { + this.listClass = listClass; + } + + public String getIsDefault() { + return isDefault; + } + + public void setIsDefault(String isDefault) { + this.isDefault = isDefault; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/bean/NodeBean.java b/mylibrary/src/main/java/com/dahe/mylibrary/bean/NodeBean.java new file mode 100644 index 0000000..7da5641 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/bean/NodeBean.java @@ -0,0 +1,354 @@ +package com.dahe.mylibrary.bean; + +import java.io.Serializable; + +public class NodeBean implements Serializable { + + + private String searchValue; + private String createBy; + private String createTime; + private String updateBy; + private String updateTime; + private String remark; + private String planId; + private String nodeId; + private String nodeType; + private String orderId; + private String nodeName; + private String address; + private String contacts; + private String contactsPhone; + private String contacts_phone; + private String provinceId; + private String provinceName; + private String cityId; + private String cityName; + private String countyId; + private String countyName; + private String planIndex; + private String remarks; + private String node_name; + private String warehouseId; + private String warehouseName; + private String isSelect; + private String w_child_id; + private String firstNameCode; + + + private String wChildId; + private String waybillId; + private String freighter; + private String freighterId; + private String node; + private String state; + private String isSelectOld; + private String dockingPhone; + private String docking; + + public String getwChildId() { + return wChildId; + } + + public void setwChildId(String wChildId) { + this.wChildId = wChildId; + } + + public String getWaybillId() { + return waybillId; + } + + public void setWaybillId(String waybillId) { + this.waybillId = waybillId; + } + + public String getFreighter() { + return freighter; + } + + public void setFreighter(String freighter) { + this.freighter = freighter; + } + + public String getFreighterId() { + return freighterId; + } + + public void setFreighterId(String freighterId) { + this.freighterId = freighterId; + } + + public String getNode() { + return node; + } + + public void setNode(String node) { + this.node = node; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getIsSelectOld() { + return isSelectOld; + } + + public void setIsSelectOld(String isSelectOld) { + this.isSelectOld = isSelectOld; + } + + public String getDockingPhone() { + return dockingPhone; + } + + public void setDockingPhone(String dockingPhone) { + this.dockingPhone = dockingPhone; + } + + public String getDocking() { + return docking; + } + + public void setDocking(String docking) { + this.docking = docking; + } + + public String getWarehouseId() { + return warehouseId; + } + + public void setWarehouseId(String warehouseId) { + this.warehouseId = warehouseId; + } + + public String getWarehouseName() { + return warehouseName; + } + + public void setWarehouseName(String warehouseName) { + this.warehouseName = warehouseName; + } + + public String getFirstNameCode() { + return firstNameCode; + } + + public void setFirstNameCode(String firstNameCode) { + this.firstNameCode = firstNameCode; + } + + public String getW_child_id() { + return w_child_id; + } + + public void setW_child_id(String w_child_id) { + this.w_child_id = w_child_id; + } + + public String isSelect() { + return isSelect; + } + + public void setSelect(String select) { + isSelect = select; + } + + public String getNode_name() { + return node_name; + } + + public void setNode_name(String node_name) { + this.node_name = node_name; + } + + public String getContacts_phone() { + return contacts_phone; + } + + public void setContacts_phone(String contacts_phone) { + this.contacts_phone = contacts_phone; + } + + public String getSearchValue() { + return searchValue; + } + + public void setSearchValue(String searchValue) { + this.searchValue = searchValue; + } + + public String getCreateBy() { + return createBy; + } + + public void setCreateBy(String createBy) { + this.createBy = createBy; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getUpdateBy() { + return updateBy; + } + + public void setUpdateBy(String updateBy) { + this.updateBy = updateBy; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + + public String getPlanId() { + return planId; + } + + public void setPlanId(String planId) { + this.planId = planId; + } + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + public String getNodeType() { + return nodeType; + } + + public void setNodeType(String nodeType) { + this.nodeType = nodeType; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getNodeName() { + return nodeName; + } + + public void setNodeName(String nodeName) { + this.nodeName = nodeName; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getContacts() { + return contacts; + } + + public void setContacts(String contacts) { + this.contacts = contacts; + } + + public String getContactsPhone() { + return contactsPhone; + } + + public void setContactsPhone(String contactsPhone) { + this.contactsPhone = contactsPhone; + } + + public String getProvinceId() { + return provinceId; + } + + public void setProvinceId(String provinceId) { + this.provinceId = provinceId; + } + + public String getProvinceName() { + return provinceName; + } + + public void setProvinceName(String provinceName) { + this.provinceName = provinceName; + } + + public String getCityId() { + return cityId; + } + + public void setCityId(String cityId) { + this.cityId = cityId; + } + + public String getCityName() { + return cityName; + } + + public void setCityName(String cityName) { + this.cityName = cityName; + } + + public String getCountyId() { + return countyId; + } + + public void setCountyId(String countyId) { + this.countyId = countyId; + } + + public String getCountyName() { + return countyName; + } + + public void setCountyName(String countyName) { + this.countyName = countyName; + } + + public String getPlanIndex() { + return planIndex; + } + + public void setPlanIndex(String planIndex) { + this.planIndex = planIndex; + } + + public String getRemarks() { + return remarks; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } + +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/bean/StateBean.java b/mylibrary/src/main/java/com/dahe/mylibrary/bean/StateBean.java new file mode 100644 index 0000000..83f9b59 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/bean/StateBean.java @@ -0,0 +1,151 @@ +package com.dahe.mylibrary.bean; + +import java.io.Serializable; + +public class StateBean implements Serializable { + + + private String searchValue; + private String createBy; + private String createTime; + private String updateBy; + private String updateTime; + private String remark; + private String dictCode; + private String dictSort; + private String dictLabel; + private String dictValue; + private String dictType; + private String cssClass; + private String listClass; + private String isDefault; + private String status; + + public StateBean(String dictLabel, String dictValue) { + this.dictLabel = dictLabel; + this.dictValue = dictValue; + } + + public String getSearchValue() { + return searchValue; + } + + public void setSearchValue(String searchValue) { + this.searchValue = searchValue; + } + + public String getCreateBy() { + return createBy; + } + + public void setCreateBy(String createBy) { + this.createBy = createBy; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getUpdateBy() { + return updateBy; + } + + public void setUpdateBy(String updateBy) { + this.updateBy = updateBy; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getDictCode() { + return dictCode; + } + + public void setDictCode(String dictCode) { + this.dictCode = dictCode; + } + + public String getDictSort() { + return dictSort; + } + + public void setDictSort(String dictSort) { + this.dictSort = dictSort; + } + + public String getDictLabel() { + return dictLabel; + } + + public void setDictLabel(String dictLabel) { + this.dictLabel = dictLabel; + } + + public String getDictValue() { + return dictValue; + } + + public void setDictValue(String dictValue) { + this.dictValue = dictValue; + } + + public String getDictType() { + return dictType; + } + + public void setDictType(String dictType) { + this.dictType = dictType; + } + + public String getCssClass() { + return cssClass; + } + + public void setCssClass(String cssClass) { + this.cssClass = cssClass; + } + + public String getListClass() { + return listClass; + } + + public void setListClass(String listClass) { + this.listClass = listClass; + } + + public String getIsDefault() { + return isDefault; + } + + public void setIsDefault(String isDefault) { + this.isDefault = isDefault; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public static class ParamsDTO { + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/bean/TipsBean.java b/mylibrary/src/main/java/com/dahe/mylibrary/bean/TipsBean.java new file mode 100644 index 0000000..1b989cc --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/bean/TipsBean.java @@ -0,0 +1,29 @@ +package com.dahe.mylibrary.bean; + +import java.io.Serializable; + +public class TipsBean implements Serializable { + private String title; + private String content; + + public TipsBean(String title, String content) { + this.title = title; + this.content = content; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/bean/VersionBean.java b/mylibrary/src/main/java/com/dahe/mylibrary/bean/VersionBean.java new file mode 100644 index 0000000..55f51f7 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/bean/VersionBean.java @@ -0,0 +1,93 @@ +package com.dahe.mylibrary.bean; + +import java.io.Serializable; + +public class VersionBean implements Serializable { + + + + private ParamsDao data; + + public ParamsDao getData() { + return data; + } + + public void setData(ParamsDao data) { + this.data = data; + } + + public static class ParamsDao implements Serializable{ + private int versionId; + private int version; + private String versionName; + private String introduce; + private String updateType; + private String createTime; + private String remark; + private String apkUrl; + + public String getApkUrl() { + return apkUrl; + } + + public void setApkUrl(String apkUrl) { + this.apkUrl = apkUrl; + } + + public int getVersionId() { + return versionId; + } + + public void setVersionId(int versionId) { + this.versionId = versionId; + } + + public int getVersion() { + return version; + } + + public void setVersion(int version) { + this.version = version; + } + + public String getVersionName() { + return versionName; + } + + public void setVersionName(String versionName) { + this.versionName = versionName; + } + + public String getIntroduce() { + return introduce; + } + + public void setIntroduce(String introduce) { + this.introduce = introduce; + } + + public String getUpdateType() { + return updateType; + } + + public void setUpdateType(String updateType) { + this.updateType = updateType; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/callback/OnItemLongClickListener.java b/mylibrary/src/main/java/com/dahe/mylibrary/callback/OnItemLongClickListener.java new file mode 100644 index 0000000..9e949df --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/callback/OnItemLongClickListener.java @@ -0,0 +1,14 @@ +package com.dahe.mylibrary.callback; + +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +/** + * @author:luck + * @date:2020-01-13 17:58 + * @describe:长按事件 + */ +public interface OnItemLongClickListener { + void onItemLongClick(RecyclerView.ViewHolder holder, int position, View v); +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/callback/RefreshCallBack.java b/mylibrary/src/main/java/com/dahe/mylibrary/callback/RefreshCallBack.java new file mode 100644 index 0000000..adc89c3 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/callback/RefreshCallBack.java @@ -0,0 +1,14 @@ +package com.dahe.mylibrary.callback; + +/** + * 刷新的回调 + */ + +public interface RefreshCallBack { + /** + * @param stat 1刷新 2加载更多 + * @param page 当前页数 + * @param count 当前count + */ + void getRefreshDate(int stat, int page, int count); +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CarSelPopupView.java b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CarSelPopupView.java new file mode 100644 index 0000000..e93cf16 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CarSelPopupView.java @@ -0,0 +1,105 @@ +package com.dahe.mylibrary.cuspop; + +import android.content.Context; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemClickListener; +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.adapter.CarAdapter; +import com.dahe.mylibrary.adapter.NodeAdapter; +import com.dahe.mylibrary.bean.CarBean; +import com.dahe.mylibrary.bean.NodeBean; +import com.dahe.mylibrary.net.JsonUtils; +import com.dahe.mylibrary.utils.ToastUtils; +import com.lxj.xpopup.core.CenterPopupView; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class CarSelPopupView extends CenterPopupView { + + + private Context context; + private List data; + public CarSelPopupView(Context context, String data) { + super(context); + this.context = context; + ArrayList nodeBeans = JsonUtils.getInstance().jsonToList(data, CarBean.class); + this.data = nodeBeans; + } + + @Override + protected int getImplLayoutId() { + return R.layout.view_node; + } + + @Override + protected void onCreate() { + super.onCreate(); + TextView tvTitle = (TextView) findViewById(R.id.tvTitle); + ImageView ivCha = (ImageView) findViewById(R.id.ivCha); + LinearLayout llCha = (LinearLayout) findViewById(R.id.llCha); + Button btnOK = (Button) findViewById(R.id.btnOK); + RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); + recyclerView.setLayoutManager(new LinearLayoutManager(context,RecyclerView.VERTICAL,false)); + recyclerView.setHasFixedSize(true); + CarAdapter nodeAdapter = new CarAdapter(-1,data); + recyclerView.setAdapter(nodeAdapter); + + tvTitle.setText("关联司机"); + nodeAdapter.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(@NonNull @NotNull BaseQuickAdapter adapter, @NonNull @NotNull View view, int position) { + CarBean nodeSelectBean = data.get(position); + nodeSelectBean.setSelect(!nodeSelectBean.isSelect()); + nodeAdapter.notifyItemChanged(position); + } + }); + + btnOK.setOnClickListener(v -> { + if (listener!=null){ +// ArrayList temp = new ArrayList<>(); +// for (int i = 0; i < data.size(); i++) { +// CarBean nodeSelectBean = data.get(i); +// if ("1".equals(nodeSelectBean.isSelect())){ +// temp.add(nodeSelectBean); +// } +// +// } +// if (temp.size()<=0){ +// ToastUtils.showToast(context,"至少存在一个节点"); +// return; +// } + listener.okClick(JsonUtils.getInstance().toJson(nodeAdapter.getData())); +// temp = null; + dismiss(); + } + }); + llCha.setOnClickListener(v -> { + dismiss(); + }); + } + + + private OnOkListener listener; + + public CarSelPopupView setOnOkListener(OnOkListener listener) { + this.listener = listener; + return this; + } + + public interface OnOkListener { + void okClick(String data); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CenterPopupView.java b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CenterPopupView.java new file mode 100644 index 0000000..1bda565 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CenterPopupView.java @@ -0,0 +1,91 @@ +package com.dahe.mylibrary.cuspop; + +import android.app.Activity; +import android.content.Context; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemClickListener; +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.adapter.CenterSimAdapter; +import com.dahe.mylibrary.bean.StateBean; +import com.dahe.mylibrary.wapper.SelectSimAdapter; +import com.luck.picture.lib.decoration.GridSpacingItemDecoration; +import com.lxj.xpopup.impl.PartShadowPopupView; + +import java.util.List; + +/** + * Description: 自定义局部阴影弹窗 + * Create by dance, at 2018/12/21 + */ +public class CenterPopupView extends PartShadowPopupView { + private Context ctx; + private RecyclerView recyclerView; + private List wordList; + private CenterSimAdapter adapter; + private StateBean selectString; + + public CenterPopupView(@NonNull Activity context, List wordList, StateBean selectString) { + super(context); + this.wordList= wordList; + this.selectString = selectString; + } + + @Override + protected int getImplLayoutId() { + return R.layout.custom_part_shadow_popup; + } + + + @Override + protected void onCreate() { + super.onCreate(); + recyclerView = findViewById(R.id.recyclerView); + GridLayoutManager gridLayoutManager = new GridLayoutManager(ctx, 4); + recyclerView.addItemDecoration(new GridSpacingItemDecoration(4, 20, false)); + recyclerView.setLayoutManager(gridLayoutManager); + adapter = new CenterSimAdapter(-1, wordList,selectString); + recyclerView.setAdapter(adapter); + + adapter.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { + if (listener!=null){ + listener.selectChange(wordList.get(position),position); + } + ((CenterSimAdapter)adapter).setSelect(wordList.get(position)); + adapter.notifyDataSetChanged(); + dismiss(); + } + }); + + } + + @Override + protected void onShow() { + super.onShow(); + Log.e("tag", "CustomPartShadowPopupView onShow"); + } + + @Override + protected void onDismiss() { + super.onDismiss(); + Log.e("tag", "CustomPartShadowPopupView onDismiss"); + } + + + private OnSelectChangeListener listener; + public CenterPopupView setOnSelectChangeListener(OnSelectChangeListener listener){ + this.listener = listener; + return this; + } + public interface OnSelectChangeListener{ + void selectChange(StateBean item ,int postion); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CustomDicPopView.java b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CustomDicPopView.java new file mode 100644 index 0000000..7b84f67 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CustomDicPopView.java @@ -0,0 +1,90 @@ +package com.dahe.mylibrary.cuspop; + +import android.content.Context; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemClickListener; +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.adapter.SelectDicAdapter; +import com.dahe.mylibrary.bean.DictBean; +import com.dahe.mylibrary.bean.StateBean; +import com.lxj.xpopup.core.AttachPopupView; + +import java.util.List; + +/** + * Description: 自定义局部阴影弹窗 + * Create by dance, at 2018/12/21 + */ +public class CustomDicPopView extends AttachPopupView { + private Context ctx; + private RecyclerView recyclerView; + private List wordList; + private SelectDicAdapter adapter; + private int selectPos; + + public CustomDicPopView(@NonNull Context context, List wordList, int selectPos) { + super(context); + this.ctx = context; + this.wordList= wordList; + this.selectPos = selectPos; + } + + @Override + protected int getImplLayoutId() { + return R.layout.custom_dic_popup; + } + + + @Override + protected void onCreate() { + super.onCreate(); + recyclerView = findViewById(R.id.recyclerView); + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(ctx, RecyclerView.VERTICAL, false); +// recyclerView.addItemDecoration(new RecycleViewDivider(ctx,RecyclerView.VERTICAL)); + recyclerView.setLayoutManager(linearLayoutManager); + adapter = new SelectDicAdapter(-1, wordList,selectPos); + recyclerView.setAdapter(adapter); + + adapter.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { + if (listener!=null){ + listener.selectChange(wordList.get(position),position); + } + ((SelectDicAdapter)adapter).setSelect(position); + adapter.notifyDataSetChanged(); + dismiss(); + } + }); + + } + + @Override + protected void onShow() { + super.onShow(); + Log.e("tag", "CustomPartShadowPopupView onShow"); + } + + @Override + protected void onDismiss() { + super.onDismiss(); + Log.e("tag", "CustomPartShadowPopupView onDismiss"); + } + + + private OnSelectChangeListener listener; + public CustomDicPopView setOnSelectChangeListener(OnSelectChangeListener listener){ + this.listener = listener; + return this; + } + public interface OnSelectChangeListener{ + void selectChange(StateBean item ,int postion); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CustomPartShadowPopupView.java b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CustomPartShadowPopupView.java new file mode 100644 index 0000000..d42f762 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/CustomPartShadowPopupView.java @@ -0,0 +1,90 @@ +package com.dahe.mylibrary.cuspop; + +import android.app.Activity; +import android.content.Context; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemClickListener; +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.wapper.SelectSimAdapter; +import com.luck.picture.lib.decoration.GridSpacingItemDecoration; +import com.lxj.xpopup.impl.PartShadowPopupView; + +import java.util.List; + +/** + * Description: 自定义局部阴影弹窗 + * Create by dance, at 2018/12/21 + */ +public class CustomPartShadowPopupView extends PartShadowPopupView { + private Context ctx; + private RecyclerView recyclerView; + private List wordList; + private SelectSimAdapter adapter; + private String selectString; + + public CustomPartShadowPopupView(@NonNull Activity context, List wordList, String selectString) { + super(context); + this.wordList= wordList; + this.selectString = selectString; + } + + @Override + protected int getImplLayoutId() { + return R.layout.custom_part_shadow_popup; + } + + + @Override + protected void onCreate() { + super.onCreate(); + recyclerView = findViewById(R.id.recyclerView); + GridLayoutManager gridLayoutManager = new GridLayoutManager(ctx, 4); + recyclerView.addItemDecoration(new GridSpacingItemDecoration(4, 20, false)); + recyclerView.setLayoutManager(gridLayoutManager); + adapter = new SelectSimAdapter(-1, wordList,selectString); + recyclerView.setAdapter(adapter); + + adapter.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { + if (listener!=null){ + listener.selectChange(wordList.get(position),position); + } + ((SelectSimAdapter)adapter).setSelect(wordList.get(position)); + adapter.notifyDataSetChanged(); + dismiss(); + } + }); + + } + + @Override + protected void onShow() { + super.onShow(); + Log.e("tag", "CustomPartShadowPopupView onShow"); + } + + @Override + protected void onDismiss() { + super.onDismiss(); + Log.e("tag", "CustomPartShadowPopupView onDismiss"); + } + + + private OnSelectChangeListener listener; + public CustomPartShadowPopupView setOnSelectChangeListener(OnSelectChangeListener listener){ + this.listener = listener; + return this; + } + public interface OnSelectChangeListener{ + void selectChange(String item ,int postion); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/InputPopupView.java b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/InputPopupView.java new file mode 100644 index 0000000..e8e8529 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/InputPopupView.java @@ -0,0 +1,80 @@ +package com.dahe.mylibrary.cuspop; + +import android.content.Context; +import android.text.TextUtils; +import android.util.Log; +import android.widget.EditText; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.utils.ToastUtils; +import com.lxj.xpopup.core.CenterPopupView; +import com.lxj.xpopup.util.KeyboardUtils; + +/** + * Description: 自定义局部阴影弹窗 + * Create by dance, at 2018/12/21 + */ +public class InputPopupView extends CenterPopupView { + private Context ctx; + + + public InputPopupView(@NonNull Context context) { + super(context); + this.ctx = context; + } + + @Override + protected int getImplLayoutId() { + return R.layout.my_confim_popup_input; + } + + + @Override + protected void onCreate() { + super.onCreate(); + EditText etInput = findViewById(R.id.et_input); + TextView tvCancel = findViewById(R.id.tv_cancel); + TextView tvConfirm = findViewById(R.id.tv_confirm); + if (listener != null) { + tvConfirm.setOnClickListener(view -> { + if (TextUtils.isEmpty(etInput.getText().toString().trim())){ + KeyboardUtils.hideSoftInput(tvConfirm); + ToastUtils.showToast(ctx,"请填写取消原因"); + return; + } + listener.okClick(etInput.getText().toString()); + dismiss(); + }); + } + + tvCancel.setOnClickListener(v -> dismiss()); + + } + + @Override + protected void onShow() { + super.onShow(); + Log.e("tag", "CustomPartShadowPopupView onShow"); + } + + @Override + protected void onDismiss() { + super.onDismiss(); + Log.e("tag", "CustomPartShadowPopupView onDismiss"); + } + + + private OnOkListener listener; + + public InputPopupView setOnOkListener(OnOkListener listener) { + this.listener = listener; + return this; + } + + public interface OnOkListener { + void okClick(String item); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/NodePopupView.java b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/NodePopupView.java new file mode 100644 index 0000000..b376d25 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/NodePopupView.java @@ -0,0 +1,107 @@ +package com.dahe.mylibrary.cuspop; + +import android.content.Context; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemClickListener; +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.adapter.NodeAdapter; +import com.dahe.mylibrary.bean.NodeBean; +import com.dahe.mylibrary.net.JsonUtils; +import com.dahe.mylibrary.utils.ToastUtils; +import com.lxj.xpopup.core.CenterPopupView; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class NodePopupView extends CenterPopupView { + + + private Context context; + private List data; + public NodePopupView(Context context,String data) { + super(context); + this.context = context; + ArrayList nodeBeans = JsonUtils.getInstance().jsonToList(data, NodeBean.class); + this.data = nodeBeans; + } + + @Override + protected int getImplLayoutId() { + return R.layout.view_node; + } + + @Override + protected void onCreate() { + super.onCreate(); + TextView tvTitle = (TextView) findViewById(R.id.tvTitle); + ImageView ivCha = (ImageView) findViewById(R.id.ivCha); + LinearLayout llCha = (LinearLayout) findViewById(R.id.llCha); + Button btnOK = (Button) findViewById(R.id.btnOK); + RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); + recyclerView.setLayoutManager(new LinearLayoutManager(context,RecyclerView.VERTICAL,false)); + recyclerView.setHasFixedSize(true); + NodeAdapter nodeAdapter = new NodeAdapter(-1,data); + recyclerView.setAdapter(nodeAdapter); + + + nodeAdapter.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(@NonNull @NotNull BaseQuickAdapter adapter, @NonNull @NotNull View view, int position) { + NodeBean nodeSelectBean = data.get(position); + if (!"0".equals(nodeSelectBean.getState())){ + ToastUtils.showToast(context,"该节点不可操作"); + return; + } + nodeSelectBean.setSelect("1".equals(nodeSelectBean.isSelect())?"0":"1"); + nodeAdapter.notifyItemChanged(position); + } + }); + + btnOK.setOnClickListener(v -> { + if (listener!=null){ + ArrayList temp = new ArrayList<>(); + for (int i = 0; i < data.size(); i++) { + NodeBean nodeSelectBean = data.get(i); + if ("1".equals(nodeSelectBean.isSelect())){ + temp.add(nodeSelectBean); + } + + } + if (temp.size()<=0){ + ToastUtils.showToast(context,"至少存在一个节点"); + return; + } + listener.okClick(JsonUtils.getInstance().toJson(data)); + temp = null; + dismiss(); + } + }); + llCha.setOnClickListener(v -> { + dismiss(); + }); + } + + + private OnOkListener listener; + + public NodePopupView setOnOkListener(OnOkListener listener) { + this.listener = listener; + return this; + } + + public interface OnOkListener { + void okClick(String data); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/TextPopupTipsView.java b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/TextPopupTipsView.java new file mode 100644 index 0000000..4f08bd1 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/TextPopupTipsView.java @@ -0,0 +1,77 @@ +package com.dahe.mylibrary.cuspop; + +import android.content.Context; +import android.util.Log; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.bean.TipsBean; +import com.lxj.xpopup.core.CenterPopupView; + +/** + * Description: 自定义局部阴影弹窗 + * Create by dance, at 2018/12/21 + */ +public class TextPopupTipsView extends CenterPopupView { + private TipsBean data; + private Context ctx; + + + public TextPopupTipsView(@NonNull Context context, TipsBean data) { + super(context); + this.data = data; + + } + + @Override + protected int getImplLayoutId() { + return R.layout.my_confim_popup_tip; + } + + + @Override + protected void onCreate() { + super.onCreate(); + TextView etInput = findViewById(R.id.tv_input); + TextView tvTitle = findViewById(R.id.tv_title); + TextView tvCancel = findViewById(R.id.tv_cancel); + TextView tvConfirm = findViewById(R.id.tv_confirm); + tvTitle.setText(data.getTitle()); + etInput.setText(data.getContent()); + if (listener != null) { + tvConfirm.setOnClickListener(view -> { + listener.okClick(); + dismiss(); + }); + } + + tvCancel.setOnClickListener(v -> dismiss()); + + } + + @Override + protected void onShow() { + super.onShow(); + Log.e("tag", "CustomPartShadowPopupView onShow"); + } + + @Override + protected void onDismiss() { + super.onDismiss(); + Log.e("tag", "CustomPartShadowPopupView onDismiss"); + } + + + private OnOkListener listener; + + public TextPopupTipsView setOnOkListener(OnOkListener listener) { + this.listener = listener; + return this; + } + + public interface OnOkListener { + void okClick(); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/TextPopupView.java b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/TextPopupView.java new file mode 100644 index 0000000..798a3b9 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/cuspop/TextPopupView.java @@ -0,0 +1,74 @@ +package com.dahe.mylibrary.cuspop; + +import android.content.Context; +import android.util.Log; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.dahe.mylibrary.R; +import com.lxj.xpopup.core.CenterPopupView; + +/** + * Description: 自定义局部阴影弹窗 + * Create by dance, at 2018/12/21 + */ +public class TextPopupView extends CenterPopupView { + private String data; + private Context ctx; + + + public TextPopupView(@NonNull Context context,String data) { + super(context); + this.data = data; + + } + + @Override + protected int getImplLayoutId() { + return R.layout.my_confim_popup_unus; + } + + + @Override + protected void onCreate() { + super.onCreate(); + TextView etInput = findViewById(R.id.tv_input); + TextView tvCancel = findViewById(R.id.tv_cancel); + TextView tvConfirm = findViewById(R.id.tv_confirm); + etInput.setText(data); + if (listener != null) { + tvConfirm.setOnClickListener(view -> { + listener.okClick(etInput.getText().toString()); + dismiss(); + }); + } + + tvCancel.setOnClickListener(v -> dismiss()); + + } + + @Override + protected void onShow() { + super.onShow(); + Log.e("tag", "CustomPartShadowPopupView onShow"); + } + + @Override + protected void onDismiss() { + super.onDismiss(); + Log.e("tag", "CustomPartShadowPopupView onDismiss"); + } + + + private OnOkListener listener; + + public TextPopupView setOnOkListener(OnOkListener listener) { + this.listener = listener; + return this; + } + + public interface OnOkListener { + void okClick(String item); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/dialog/DialogPhotoSelect.java b/mylibrary/src/main/java/com/dahe/mylibrary/dialog/DialogPhotoSelect.java new file mode 100644 index 0000000..e06f0e3 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/dialog/DialogPhotoSelect.java @@ -0,0 +1,108 @@ +package com.dahe.mylibrary.dialog; + +import android.content.Context; +import android.os.Bundle; +import android.view.Gravity; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.dahe.mylibrary.R; + + +/** + * 头像选择 dialog + * + * @Description: + * @Author: tao + * @CreateDate: 2018/7/26 10:34 + */ +public class DialogPhotoSelect extends MyBaseDialog { + + private TextView take_photo; + private TextView select_photo; + private TextView do_cancel; + + private onSelectClickListener onSelectClickListener; + + public void setOnSelectClickListener(onSelectClickListener onSelectClickListener) { + this.onSelectClickListener = onSelectClickListener; + } + + public DialogPhotoSelect(@NonNull Context context) { + super(context); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.dialog_photo_select); + + initView(); + initListener(); + } + + private void initView() { + take_photo = findViewById( R.id.take_photo); + select_photo = findViewById(R.id.select_photo); + do_cancel = findViewById(R.id.do_cancel); + } + + private void initListener() { + + //拍照 + take_photo.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dismiss(); + onSelectClickListener.onTakePhoto(); + } + }); + + //相册选择 + select_photo.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dismiss(); + onSelectClickListener.onSelectPhoto(); + } + }); + + do_cancel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dismiss(); + } + }); + + + } + + @Override + public void init(@NonNull Context context) { + Window window = getWindow(); + window.setWindowAnimations(R.style.BottomAnim); + window.setGravity( Gravity.BOTTOM); + //默认的Dialog只有5/6左右的宽度,改为全屏宽度,由dialog的布局自己来决定实际显示宽度 + window.getDecorView().setPadding(0, 0, 0, 0); + WindowManager.LayoutParams lp = window.getAttributes(); + lp.width = WindowManager.LayoutParams.MATCH_PARENT; + lp.height = WindowManager.LayoutParams.WRAP_CONTENT; + window.setAttributes(lp); + } + + @Override + public boolean isCancelAble() { + return true; + } + + public interface onSelectClickListener { + + void onTakePhoto(); + + void onSelectPhoto(); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/dialog/MyBaseDialog.java b/mylibrary/src/main/java/com/dahe/mylibrary/dialog/MyBaseDialog.java new file mode 100644 index 0000000..74b915f --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/dialog/MyBaseDialog.java @@ -0,0 +1,55 @@ +package com.dahe.mylibrary.dialog; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.view.Gravity; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; + +import com.dahe.mylibrary.R; + + +/** + * Dialog 基类 基类 基类 + *

+ * 以后再写Dialog,都要继承这个 + * + * @Description: + * @Author: tao + * @CreateDate: 2018/7/26 10:29 + */ +public class MyBaseDialog extends Dialog { + + + public MyBaseDialog(@NonNull Context context) { + super(context, R.style.MyBaseDialog); + init(context); + } + + public void init(@NonNull Context context) { + Window window = getWindow(); + window.setWindowAnimations(R.style.BottomAnim); + window.setGravity(Gravity.CENTER); + //默认的Dialog只有5/6左右的宽度,改为全屏宽度,由dialog的布局自己来决定实际显示宽度 + window.getDecorView().setPadding(0, 0, 0, 0); + WindowManager.LayoutParams lp = window.getAttributes(); + lp.width = WindowManager.LayoutParams.MATCH_PARENT; + lp.height = WindowManager.LayoutParams.WRAP_CONTENT; + window.setAttributes(lp); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setCancelable(isCancelAble()); + setCanceledOnTouchOutside(isCancelAble()); + } + + public boolean isCancelAble() { + return false; + } + +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/dialog/VersionDialog.java b/mylibrary/src/main/java/com/dahe/mylibrary/dialog/VersionDialog.java new file mode 100644 index 0000000..383c55f --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/dialog/VersionDialog.java @@ -0,0 +1,21 @@ +package com.dahe.mylibrary.dialog; + +import android.app.Dialog; +import android.content.Context; + +/** + * Created by Allen Liu on 2017/2/23. + */ +public class VersionDialog extends Dialog { + private int res; + + public VersionDialog(Context context, int theme, int res) { + super(context, theme); + getWindow().setBackgroundDrawableResource(android.R.color.transparent); + // TODO 自动生成的构造函数存根 + setContentView(res); + this.res = res; + setCanceledOnTouchOutside(false); + } + +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/glide/AppGlideModule.java b/mylibrary/src/main/java/com/dahe/mylibrary/glide/AppGlideModule.java new file mode 100644 index 0000000..2387881 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/glide/AppGlideModule.java @@ -0,0 +1,35 @@ +package com.dahe.mylibrary.glide; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.Registry; +import com.bumptech.glide.annotation.GlideModule; +import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader; +import com.bumptech.glide.load.model.GlideUrl; + +import org.jetbrains.annotations.NotNull; + +import java.io.InputStream; + +import okhttp3.OkHttpClient; + +/** + * @ClassName AppGlideModule + * @Author 用户 + * @Date 2021/10/11 10:13 + * @Description TODO + */ + +@GlideModule +public class AppGlideModule extends com.bumptech.glide.module.AppGlideModule { + + @Override + public void registerComponents(@NonNull @NotNull Context context, @NonNull @NotNull Glide glide, @NonNull @NotNull Registry registry) { + super.registerComponents(context, glide, registry); + OkHttpClient client = UnsafeOkHttpClient.getUnsafeOkHttpClient(); + registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(client)); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/glide/UnsafeOkHttpClient.java b/mylibrary/src/main/java/com/dahe/mylibrary/glide/UnsafeOkHttpClient.java new file mode 100644 index 0000000..da9e54e --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/glide/UnsafeOkHttpClient.java @@ -0,0 +1,67 @@ +package com.dahe.mylibrary.glide; + +import java.security.cert.CertificateException; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import okhttp3.OkHttpClient; + +/** + * @ClassName UnsafeOkHttpClient + * @Author 用户 + * @Date 2021/10/11 10:16 + * @Description TODO + */ +public class UnsafeOkHttpClient { + public static OkHttpClient getUnsafeOkHttpClient() { + try { + // Create a trust manager that does not validate certificate chains + final TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + @Override + public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new java.security.cert.X509Certificate[]{}; + } + } + }; + + // Install the all-trusting trust manager + final SSLContext sslContext = SSLContext.getInstance("SSL"); + sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); + + // Create an ssl socket factory with our all-trusting manager + final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); + + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]); + builder.hostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }); + + builder.connectTimeout(20, TimeUnit.SECONDS); + builder.readTimeout(20,TimeUnit.SECONDS); + + OkHttpClient okHttpClient = builder.build(); + return okHttpClient; + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/net/CommonResponseBean.java b/mylibrary/src/main/java/com/dahe/mylibrary/net/CommonResponseBean.java new file mode 100644 index 0000000..d6ac17a --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/net/CommonResponseBean.java @@ -0,0 +1,73 @@ +package com.dahe.mylibrary.net; + +import java.io.Serializable; + +/** + * 返回通用的实体类 + */ + +public class CommonResponseBean implements Serializable { + private T data; + private int code; + private String info; + private String msg; + private String url; + private String fileName; + private boolean success; + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getInfo() { + return info; + } + + public void setInfo(String info) { + this.info = info; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/net/ErrorResponse.java b/mylibrary/src/main/java/com/dahe/mylibrary/net/ErrorResponse.java new file mode 100644 index 0000000..d2998e9 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/net/ErrorResponse.java @@ -0,0 +1,22 @@ +package com.dahe.mylibrary.net; + +public class ErrorResponse { + private int code; + private String msg; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/net/FileInterceptor.java b/mylibrary/src/main/java/com/dahe/mylibrary/net/FileInterceptor.java new file mode 100644 index 0000000..d373b7c --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/net/FileInterceptor.java @@ -0,0 +1,60 @@ +package com.dahe.mylibrary.net; + +import android.util.Log; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; + +import okhttp3.Interceptor; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okio.Buffer; +import okio.BufferedSource; + +/** + * 文件上传Interceptor + */ + +public class FileInterceptor implements Interceptor { + private static final String TAG = "FileInterceptor"; + private File mFile; + + public FileInterceptor(File mFile) { + this.mFile = mFile; + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request request = chain.request(); + request = request.newBuilder() + .post(RequestBody.create(MediaType.parse("application/file; charset=utf-8"), mFile)) + .build(); + Response response = chain.proceed(request); + Log.i(TAG, "url= " + request.body()); + Log.i(TAG, "method= " + request.method()); + ResponseBody responseBody = response.body(); + //为了不消耗buffer,我们这里使用source先获得buffer对象,然后clone()后使用 + BufferedSource source = responseBody.source(); + source.request(Long.MAX_VALUE); // Buffer the entire body. + //获得返回的数据 + Buffer buffer = source.buffer(); + //使用前clone()下,避免直接消耗 + String responseBodyStr = buffer.clone().readString(Charset.forName("UTF-8")); + Log.i(TAG, "result-body= " + responseBodyStr); + try { + JSONObject jsonObject = new JSONObject(responseBodyStr); + responseBody = ResponseBody.create(MediaType.parse("application/json; charset=utf-8"), jsonObject.getString("response")); + } catch (JSONException e) { + e.printStackTrace(); + } + response = response.newBuilder().body(responseBody).build(); + return response; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/net/GsonResponseBodyConverter.java b/mylibrary/src/main/java/com/dahe/mylibrary/net/GsonResponseBodyConverter.java new file mode 100644 index 0000000..5ce33b2 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/net/GsonResponseBodyConverter.java @@ -0,0 +1,74 @@ +package com.dahe.mylibrary.net; + +import com.google.gson.Gson; + +import org.json.JSONObject; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.nio.charset.Charset; + +import okhttp3.ResponseBody; +import okio.Buffer; +import okio.BufferedSource; +import retrofit2.Converter; + + +public class GsonResponseBodyConverter implements Converter { + private final Gson gson; + private final Type type; + + + public GsonResponseBodyConverter(Gson gson, Type type) { + this.gson = gson; + this.type = type; + } + + @Override + public T convert(ResponseBody value) throws IOException { + + //为了不消耗buffer,我们这里使用source先获得buffer对象,然后clone()后使用 + BufferedSource source = value.source(); + source.request(Long.MAX_VALUE); // Buffer the entire body. + //获得返回的数据 + Buffer buffer = source.buffer(); + //使用前clone()下,避免直接消耗 + String responseBodyStr = buffer.clone().readString(Charset.forName("UTF-8")); + try { + + JSONObject jsonObject = new JSONObject(responseBodyStr); + int code = jsonObject.optInt("code"); + if (-1 == code) { + jsonObject.put("data", new JSONObject()); +// ErrorResponse errorResponse = gson.fromJson(response, ErrorResponse.class); + //抛一个自定义ResultException 传入失败时候的状态码,和信息 + + throw new ResultException(-1, "errorResponse.getMsg()"); + +// return gson.fromJson(responseBodyStr,type); + } + } catch (Exception e) { + e.printStackTrace(); + } + return gson.fromJson(responseBodyStr, type); + + +// String response = value.string(); +// //先将返回的json数据解析到Response中,如果code==200,则解析到我们的实体基类中,否则抛异常 +// Response httpResult = gson.fromJson(response, Response.class); +// if (httpResult.code()==200){ +// //200的时候就直接解析,不可能出现解析异常。因为我们实体基类中传入的泛型,就是数据成功时候的格式 +// return gson.fromJson(response,type); +// }else { +// ErrorResponse errorResponse = gson.fromJson(response,ErrorResponse.class); +// //抛一个自定义ResultException 传入失败时候的状态码,和信息 +// try { +// throw new ResultException(errorResponse.getCode(),errorResponse.getMsg()); +// } catch (ResultException e) { +// e.printStackTrace(); +// } +// return null; +// } + } +} + diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/net/JsonInterceptor.java b/mylibrary/src/main/java/com/dahe/mylibrary/net/JsonInterceptor.java new file mode 100644 index 0000000..27e7ddc --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/net/JsonInterceptor.java @@ -0,0 +1,67 @@ +package com.dahe.mylibrary.net; + +import android.text.TextUtils; +import android.util.Log; + + +import com.google.zxing.common.StringUtils; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.IOException; +import java.nio.charset.Charset; + +import okhttp3.Interceptor; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okio.Buffer; +import okio.BufferedSource; + +/** + * json的Interceptor + */ + +public class JsonInterceptor implements Interceptor { + private static final String TAG = "JsonInterceptor"; + + public JsonInterceptor() { + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request request = chain.request(); + Response response = chain.proceed(request); + ResponseBody responseBody = response.body(); + //为了不消耗buffer,我们这里使用source先获得buffer对象,然后clone()后使用 + BufferedSource source = responseBody.source(); + source.request(Long.MAX_VALUE); // Buffer the entire body. + //获得返回的数据 + Buffer buffer = source.buffer(); + //使用前clone()下,避免直接消耗 + String responseBodyStr = buffer.clone().readString(Charset.forName("UTF-8")); + Log.i(TAG, "result-body= " + responseBodyStr); + try { + JSONObject jsonObject = new JSONObject(responseBodyStr); + String str = jsonObject.optString("data"); + int code = jsonObject.optInt("code"); + if (-1 == code) { + jsonObject.put("data", new JSONObject()); + throw new ResultException(); + } else { + if (TextUtils.isEmpty(str)) { + jsonObject.put("data", new JSONObject()); + } + } + + String data = jsonObject.toString(); + responseBody = ResponseBody.create(MediaType.parse("application/json; charset=utf-8"), data); + } catch (Exception e) { + e.printStackTrace(); + } + response = response.newBuilder().body(responseBody).build(); + return response; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/net/JsonUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/net/JsonUtils.java new file mode 100644 index 0000000..37d91af --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/net/JsonUtils.java @@ -0,0 +1,91 @@ +package com.dahe.mylibrary.net; + +import android.util.Log; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonIOException; +import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.lang.reflect.Type; +import java.util.ArrayList; + +/** + * 利用Gson反射对象类型,将json转化为对象 + */ +public class JsonUtils { + private Gson mGson = null; + private static JsonUtils mUtils; + + public static JsonUtils getInstance() { + if (mUtils == null) { + return new JsonUtils(); + } else { + return mUtils; + } + } + + public Gson getGson() { + if (null == mGson) { + mGson = new GsonBuilder().serializeNulls().create(); + } + return mGson; + } + + public String toJson(Object o){ + return getGson().toJson(o); + } + + /** + * 将json数组转化为List + * + * @param json json字符串 + * @param classOfT 对应实体类型 + * @return 实体列表 + */ + public ArrayList jsonToList(String json, Class classOfT) { + try { + if (mGson == null) { + // 不要直接new Gson是为了避免放回结果为null的这种情况 + mGson = new GsonBuilder().serializeNulls().create(); + } + Type type = new TypeToken>() { + }.getType(); + ArrayList jsonObjs = mGson.fromJson(json, type); + + ArrayList listOfT = new ArrayList(); + for (JsonObject jsonObj : jsonObjs) { + listOfT.add(mGson.fromJson(jsonObj, classOfT)); + } + return listOfT; + } catch (Exception e) { + return null; + } + } + + public T fromJson(String json, Class type) throws JsonIOException, JsonSyntaxException { + try { + JSONObject object = new JSONObject(json); + json = object.getString("response"); + Log.i("fromJson: ", json); + } catch (JSONException e) { + e.printStackTrace(); + } + return getGson().fromJson(json, type); + } + + public T fromJson(String json, Type type) { + return getGson().fromJson(json, type); + } + + public T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException { + return getGson().fromJson(reader, typeOfT); + } + +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/net/PagerBean.java b/mylibrary/src/main/java/com/dahe/mylibrary/net/PagerBean.java new file mode 100644 index 0000000..5ce514d --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/net/PagerBean.java @@ -0,0 +1,47 @@ +package com.dahe.mylibrary.net; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Administrator on 2018\8\26 0026. + */ +public class PagerBean { + private int total; + private int count; + private int more; + + private ArrayList rows; + + public ArrayList getRows() { + return rows; + } + + public void setRows(ArrayList rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public int getMore() { + return more; + } + + public void setMore(int more) { + this.more = more; + } +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/net/PagingBean.java b/mylibrary/src/main/java/com/dahe/mylibrary/net/PagingBean.java new file mode 100644 index 0000000..7aa11f5 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/net/PagingBean.java @@ -0,0 +1,46 @@ +package com.dahe.mylibrary.net; + +import java.io.Serializable; + +/** + * 返回通用的实体类 + */ + +public class PagingBean implements Serializable { + private T data; + private int code; + private String count; + private String msg; + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getCount() { + return count; + } + + public void setCount(String count) { + this.count = count; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/net/ResponseConverterFactory.java b/mylibrary/src/main/java/com/dahe/mylibrary/net/ResponseConverterFactory.java new file mode 100644 index 0000000..7d040ed --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/net/ResponseConverterFactory.java @@ -0,0 +1,44 @@ +package com.dahe.mylibrary.net; + +import com.google.gson.Gson; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import okhttp3.RequestBody; +import okhttp3.ResponseBody; +import retrofit2.Converter; +import retrofit2.Retrofit; + +public class ResponseConverterFactory extends Converter.Factory { + + public static ResponseConverterFactory create() { + return create(new Gson()); + } + + + public static ResponseConverterFactory create(Gson gson) { + return new ResponseConverterFactory(gson); + } + + private final Gson gson; + + private ResponseConverterFactory(Gson gson) { + if (gson == null) throw new NullPointerException("gson == null"); + this.gson = gson; + } + + @Override + public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { + //返回我们自定义的Gson响应体变换器 + return new GsonResponseBodyConverter<>(gson, type); + } + + @Override + public Converter requestBodyConverter(Type type, + Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { + //返回我们自定义的Gson响应体变换器 + return new GsonResponseBodyConverter<>(gson,type); + } +} + diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/net/ResultException.java b/mylibrary/src/main/java/com/dahe/mylibrary/net/ResultException.java new file mode 100644 index 0000000..31ffeed --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/net/ResultException.java @@ -0,0 +1,12 @@ +package com.dahe.mylibrary.net; + +public class ResultException extends Exception { + + public ResultException() { + super(); + // TODO Auto-generated constructor stub + } + + public ResultException(int code, String msg) { + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/recycleviewswipe/GridSpacingItemDecoration.java b/mylibrary/src/main/java/com/dahe/mylibrary/recycleviewswipe/GridSpacingItemDecoration.java new file mode 100644 index 0000000..017eb0f --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/recycleviewswipe/GridSpacingItemDecoration.java @@ -0,0 +1,43 @@ +package com.dahe.mylibrary.recycleviewswipe; + +import android.graphics.Rect; +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration { + + private int spanCount; //列数 + private int spacing; //间隔 + private boolean includeEdge; //是否包含边缘 + + public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) { + this.spanCount = spanCount; + this.spacing = spacing; + this.includeEdge = includeEdge; + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + + //这里是关键,需要根据你有几列来判断 + int position = parent.getChildAdapterPosition(view); // item position + int column = position % spanCount; // item column + + if (includeEdge) { + outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing) + outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing) + + if (position < spanCount) { // top edge + outRect.top = spacing; + } + outRect.bottom = spacing; // item bottom + } else { + outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing) + outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f / spanCount) * spacing) + if (position >= spanCount) { + outRect.top = spacing; // item top + } + } + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/recycleviewswipe/MyDecoration.java b/mylibrary/src/main/java/com/dahe/mylibrary/recycleviewswipe/MyDecoration.java new file mode 100644 index 0000000..faf06a3 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/recycleviewswipe/MyDecoration.java @@ -0,0 +1,110 @@ +package com.dahe.mylibrary.recycleviewswipe; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.view.View; + +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.dahe.mylibrary.R; + + +public class MyDecoration extends RecyclerView.ItemDecoration{ + + public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; + + public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; + + private Drawable mDivider; + + private int mOrientation; + + /** + * 分割线缩进值 + */ + private int inset; + + private Paint paint; + + /** + * @param context + * @param orientation layout的方向 + * @param drawable 引入的drawable的ID + * @param inset 分割线缩进值 + */ + public MyDecoration(Context context, int orientation, int drawable, int inset) { + mDivider = context.getResources().getDrawable(drawable); + this.inset = inset; + paint = new Paint(); + paint.setColor(context.getResources().getColor(R.color.white)); + paint.setStyle(Paint.Style.FILL); + paint.setAntiAlias(true); + setOrientation(orientation); + } + + public void setOrientation(int orientation) { + if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { + throw new IllegalArgumentException("invalid orientation"); + } + mOrientation = orientation; + } + + @Override + public void onDraw(Canvas c, RecyclerView parent) { + if (mOrientation == VERTICAL_LIST) { + drawVertical(c, parent); + } else { + drawHorizontal(c, parent); + } + } + + private void drawVertical(Canvas c, RecyclerView parent) { + final int left = parent.getPaddingLeft(); + final int right = parent.getWidth() - parent.getPaddingRight(); + + final int childCount = parent.getChildCount(); + //最后一个item不画分割线 + for (int i = 0; i < childCount - 1; i++) { + final View child = parent.getChildAt(i); + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); + final int top = child.getBottom() + params.bottomMargin; + final int bottom = top + mDivider.getIntrinsicHeight(); + if (inset > 0) { + c.drawRect(left, top, right, bottom, paint); + mDivider.setBounds(left + inset, top, right - inset, bottom); + } else { + mDivider.setBounds(left, top, right, bottom); + } + mDivider.draw(c); + } + } + + private void drawHorizontal(Canvas c, RecyclerView parent) { + final int top = parent.getPaddingTop(); + final int bottom = parent.getHeight() - parent.getPaddingBottom(); + + final int childCount = parent.getChildCount(); + for (int i = 0; i < childCount - 1; i++) { + final View child = parent.getChildAt(i); + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); + final int left = child.getRight() + params.rightMargin; + final int right = left + mDivider.getIntrinsicHeight(); + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(c); + } + } + + //由于Divider也有宽高,每一个Item需要向下或者向右偏移 + @Override + public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { + if (mOrientation == VERTICAL_LIST) { + outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); + } else { + outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); + } + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/recycleviewswipe/RecycleViewDivider.java b/mylibrary/src/main/java/com/dahe/mylibrary/recycleviewswipe/RecycleViewDivider.java new file mode 100644 index 0000000..77bb594 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/recycleviewswipe/RecycleViewDivider.java @@ -0,0 +1,156 @@ +package com.dahe.mylibrary.recycleviewswipe; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.view.View; + +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +public class RecycleViewDivider extends RecyclerView.ItemDecoration { + + private Paint mPaint; + //分割线 + private Drawable mDivider; + //分割线高度,默认是1px + private int mDividerHeight = 1; + //列表的方向:LinearLayoutManager.VERTICAL或LinearLayoutManager.HORIZONTAL + private int mOrientation; + + private static final int[] ATTRS = new int[]{android.R.attr.listDivider}; + + /** + * + * 默认分割线:高度为2px,颜色为灰色 + * 获取属性值, + * + * @param context + * @param orientation 列表方向 + */ + + public RecycleViewDivider(Context context, int orientation){ + if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) { + throw new IllegalArgumentException("请输入正确的参数!"); + } + mOrientation = orientation; + final TypedArray array = context.obtainStyledAttributes(ATTRS); + mDivider = array.getDrawable(0); + array.recycle(); + mDividerHeight = mDivider.getIntrinsicHeight(); + } + + /** + * 自定义分割线 + * + * @param context + * @param orientation 列表方向 + * @param drawableId 分割线图片 + */ + public RecycleViewDivider(Context context, int orientation, int drawableId) { + if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) { + throw new IllegalArgumentException("请输入正确的参数!"); + } + mOrientation = orientation; + + mDivider = ContextCompat.getDrawable(context, drawableId); + mDividerHeight = mDivider.getIntrinsicHeight(); + } + + /** + * 自定义分割线 + * + * @param orientation 列表方向 + * @param dividerHeight 分割线高度 + * @param dividerColor 分割线颜色 + */ + public RecycleViewDivider(int orientation, int dividerHeight, int dividerColor) { + + if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) { + throw new IllegalArgumentException("请输入正确的参数!"); + } + mOrientation = orientation; + + mDividerHeight = dividerHeight; + + mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mPaint.setColor(dividerColor); + mPaint.setStyle(Paint.Style.FILL); + + } + + //获取分割线尺寸 + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + + if (mOrientation == LinearLayoutManager.VERTICAL) { + outRect.set(0, 0, 0, mDividerHeight); + } else { + outRect.set(0, 0, mDividerHeight, 0); + } + } + + @Override + public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { + super.onDraw(c, parent, state); + if(mOrientation==LinearLayoutManager.VERTICAL){ + drawVerticalLine(c,parent); + }else{ + drawHorizontalLine(c,parent); + } + } + + //为横方向item, 画分割线 + private void drawHorizontalLine(Canvas canvas, RecyclerView parent) { + + final int top = parent.getPaddingTop(); + final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom(); + final int childSize = parent.getChildCount(); + for (int i = 0; i < childSize - 1; i++) { + if ((i+1) % 3 != 0) { + final View child = parent.getChildAt(i); + RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); + final int left = child.getRight() + layoutParams.rightMargin; + final int right = left + mDividerHeight; + if (mDivider != null) { + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(canvas); + } + if (mPaint != null) { + canvas.drawRect(left, top, right, bottom, mPaint); + } + } + } + } + + //为竖方向item, 画分割线 + private void drawVerticalLine(Canvas canvas, RecyclerView parent) { + + final int left = parent.getPaddingLeft(); + final int right = parent.getMeasuredWidth() - parent.getPaddingRight(); + final int childSize = parent.getChildCount(); + for (int i = 0; i < childSize; i++) { + if (i < childSize -1) { + final View child = parent.getChildAt(i); + RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); + final int top = child.getBottom() + layoutParams.bottomMargin; + final int bottom = top + mDividerHeight; + + if (mDivider != null) { + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(canvas); + } + + if (mPaint != null) { + canvas.drawRect(left, top, right, bottom, mPaint); + } + + } + } + } +} + diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/ActivityUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/ActivityUtils.java new file mode 100644 index 0000000..af47200 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/ActivityUtils.java @@ -0,0 +1,330 @@ +package com.dahe.mylibrary.utils; + + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.Bundle; + +import androidx.annotation.NonNull; + + +import com.dahe.mylibrary.CommonBaseLibrary; + +import java.util.List; + +/** + *

+ *     author: Blankj
+ *     blog  : http://blankj.com
+ *     time  : 2016/09/23
+ *     desc  : Activity相关工具类
+ * 
+ */ +public class ActivityUtils { + + public ActivityUtils() { + throw new UnsupportedOperationException("u can't instantiate me..."); + } + + /** + * 启动Activity + * + * @param context + * @param clz + * @param bundle + */ + public static void startActivity(@NonNull Context context, @NonNull Class clz, Bundle bundle) { + Intent intent = new Intent(context, clz); + if (null != bundle) intent.putExtras(bundle); + context.startActivity(intent); + } + + /** + * 启动Activity + * + * @param context + * @param clz + * @param bundle + */ + public static void startPushActivity(@NonNull Context context, @NonNull Class clz, Bundle bundle) { + Intent intent = new Intent(context, clz); + if (null != bundle){ + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtras(bundle); + } + context.startActivity(intent); + } + + /** + * 启动Activity + * + * @param context + * @param clz + */ + public static void startActivity(@NonNull Context context, @NonNull Class clz) { + startActivity(context, clz, null); + } + + /** + * 启动Activity + * + * @param activity + * @param clz + * @param bundle + */ + public static void startActivityForResult(@NonNull Activity activity, @NonNull Class clz, Bundle bundle, int requestCode) { + Intent intent = new Intent(activity, clz); + if (null != bundle) intent.putExtras(bundle); + activity.startActivityForResult(intent, requestCode); + } + + /** + * 启动Activity + * + * @param activity + * @param clz + */ + public static void startActivityForResult(@NonNull Activity activity, @NonNull Class clz, int requestCode) { + startActivityForResult(activity, clz, null, requestCode); + } + + +// /** +// * 跳转登录界面 +// * +// * @param context +// * @param finishOthers 是否结束其他的activity true结束 false 不结束 +// */ +// public static void openLoginActivity(@NonNull Context context, boolean finishOthers) { +// Intent intent = new Intent(context, LoginMainActivity.class); +// Bundle bundle = new Bundle(); +// bundle.putBoolean("finishOthers", finishOthers); +// intent.putExtras(bundle); +// context.startActivity(intent); +// } + +// /** +// * 启动前必须登录Activity +// * +// * @param context +// * @param clz +// */ +// public static void startActivityByLogin(@NonNull Context context, @NonNull Class clz) { +// startActivityByLogin(context, clz, null); +// } + + + /** + * 回到桌面 + */ + public static void startHomeActivity(Context context) { + Intent homeIntent = new Intent(Intent.ACTION_MAIN); + homeIntent.addCategory(Intent.CATEGORY_HOME); + context.startActivity(homeIntent); + } + + /** + * 获取Activity栈链表 + * + * @return Activity栈链表 + */ + public static List getActivityList() { + return CommonBaseLibrary.activityList; + } + + /** + * 获取启动项Activity + * + * @param packageName 包名 + * @return 启动项Activity + */ + public static String getLauncherActivity(@NonNull final String packageName) { + Intent intent = new Intent(Intent.ACTION_MAIN, null); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + PackageManager pm = CommonBaseLibrary.getApplication().getPackageManager(); + List info = pm.queryIntentActivities(intent, 0); + for (ResolveInfo aInfo : info) { + if (aInfo.activityInfo.packageName.equals(packageName)) { + return aInfo.activityInfo.name; + } + } + return "no " + packageName; + } + + /** + * 获取栈顶Activity + * + * @return 栈顶Activity + */ + public static Activity getTopActivity() { + if (CommonBaseLibrary.topActivity != null) { + Activity activity = CommonBaseLibrary.topActivity.get(); + if (activity != null) { + return activity; + } + } + List activities = CommonBaseLibrary.activityList; + int size = activities.size(); + return size > 0 ? activities.get(size - 1) : null; + } + + /** + * 判断Activity是否存在栈中 + * + * @param activity activity + * @return {@code true}: 存在
{@code false}: 不存在 + */ + public static boolean isActivityExistsInStack(@NonNull final Activity activity) { + List activities = CommonBaseLibrary.activityList; + for (Activity aActivity : activities) { + if (aActivity.equals(activity)) { + return true; + } + } + return false; + } + + /** + * 判断Activity是否存在栈中 + * + * @param clz activity类 + * @return {@code true}: 存在
{@code false}: 不存在 + */ + public static boolean isActivityExistsInStack(@NonNull final Class clz) { + List activities = CommonBaseLibrary.activityList; + for (Activity aActivity : activities) { + if (aActivity.getClass().equals(clz)) { + return true; + } + } + return false; + } + + /** + * 结束Activity + * + * @param activity activity + */ + public static void finishActivity(@NonNull final Activity activity) { + activity.finish(); + } + + + /** + * 结束Activity + * + * @param clz activity类 + */ + public static void finishActivity(@NonNull final Class clz) { + List activities = CommonBaseLibrary.activityList; + for (Activity activity : activities) { + if (activity.getClass().equals(clz)) { + activity.finish(); + } + } + } + + /** + * 结束到指定Activity + * + * @param activity activity + * @param isIncludeSelf 是否结束该activity自己 + */ + public static boolean finishToActivity(@NonNull final Activity activity, + final boolean isIncludeSelf) { + List activities = CommonBaseLibrary.activityList; + for (int i = activities.size() - 1; i >= 0; --i) { + Activity aActivity = activities.get(i); + if (aActivity.equals(activity)) { + if (isIncludeSelf) { + finishActivity(aActivity); + } + return true; + } + finishActivity(aActivity); + } + return false; + } + + /** + * 结束到指定Activity + * + * @param isIncludeSelf 是否结束该activity自己 + */ + public static boolean finishToActivity(@NonNull final Class clz, + final boolean isIncludeSelf) { + List activities = CommonBaseLibrary.activityList; + for (int i = activities.size() - 1; i >= 0; --i) { + Activity aActivity = activities.get(i); + if (aActivity.getClass().equals(clz)) { + if (isIncludeSelf) { + finishActivity(aActivity); + } + return true; + }else{ + finishActivity(aActivity); + } +// finishActivity(aActivity); + } + return false; + } + + /** + * 结束除最新之外的同类型Activity + *

也就是让栈中最多只剩下一种类型的Activity

+ * + * @param clz activity类 + */ + public static void finishOtherActivitiesExceptNewest(@NonNull final Class clz) { + List activities = CommonBaseLibrary.activityList; + boolean flag = false; + for (int i = activities.size() - 1; i >= 0; i--) { + Activity activity = activities.get(i); + if (activity.getClass().equals(clz)) { + if (flag) { + finishActivity(activity); + } else { + flag = true; + } + } else { + finishActivity(activity); + } + } + } + + /** + * 清除除本activity之外所有的activity + * + * @param clz 本activity的类名 + */ + public static void finishOtherActivities(@NonNull final Class clz) { + List activities = CommonBaseLibrary.activityList; + for (Activity activity : activities) { + if (!activity.getClass().equals(clz)) { + finishActivity(activity); + } + } + } + + /** + * 结束所有activity + */ + public static void finishAllActivities() { + List activityList = CommonBaseLibrary.activityList; + for (int i = activityList.size() - 1; i >= 0; --i) {// 从栈顶开始移除 + Activity activity = activityList.get(i); + activity.finish();// 在onActivityDestroyed发生remove + } + } + + private static Context getActivityOrApp() { + Activity topActivity = getTopActivity(); + return topActivity == null ? CommonBaseLibrary.getApplication() : topActivity; + } + + +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/AppUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/AppUtils.java new file mode 100644 index 0000000..e556926 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/AppUtils.java @@ -0,0 +1,1062 @@ +package com.dahe.mylibrary.utils; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.ActivityManager; +import android.app.AppOpsManager; +import android.app.usage.UsageStats; +import android.app.usage.UsageStatsManager; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.pm.Signature; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Build; +import android.provider.Settings; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.core.content.FileProvider; + + +import com.dahe.mylibrary.CommonBaseLibrary; + +import java.io.File; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; + +/** + *
+ *     author: Blankj
+ *     blog  : http://blankj.com
+ *     time  : 2016/08/02
+ *     desc  : utils about app
+ * 
+ * registerAppStatusChangedListener : 注册 App 前后台切换监听器 + * unregisterAppStatusChangedListener: 注销 App 前后台切换监听器 + * installApp : 安装 App(支持 8.0) + * installAppSilent : 静默安装 App + * uninstallApp : 卸载 App + * uninstallAppSilent : 静默卸载 App + * isAppInstalled : 判断 App 是否安装 + * isAppRoot : 判断 App 是否有 root 权限 + * isAppDebug : 判断 App 是否是 Debug 版本 + * isAppSystem : 判断 App 是否是系统应用 + * isAppForeground : 判断 App 是否处于前台 + * launchApp : 打开 App + * relaunchApp : 重启 App + * launchAppDetailsSettings : 打开 App 具体设置 + * exitApp : 关闭应用 + * getAppIcon : 获取 App 图标 + * getAppPackageName : 获取 App 包名 + * getAppName : 获取 App 名称 + * getAppPath : 获取 App 路径 + * getAppVersionName : 获取 App 版本号 + * getAppVersionCode : 获取 App 版本码 + * getAppSignature : 获取 App 签名 + * getAppSignatureSHA1 : 获取应用签名的的 SHA1 值 + * getAppSignatureSHA256 : 获取应用签名的的 SHA256 值 + * getAppSignatureMD5 : 获取应用签名的的 MD5 值 + * getAppInfo : 获取 App 信息 + * getAppsInfo : 获取所有已安装 App 信息 + * getApkInfo : 获取 Apk 信息 + */ +public final class AppUtils { + + private AppUtils() { + throw new UnsupportedOperationException("u can't instantiate me..."); + } + + /** + * Install the app. + *

Target APIs greater than 25 must hold + * {@code }

+ * + * @param filePath The path of file. + */ + public static void installApp(final String filePath) { + installApp(getFileByPath(filePath)); + } + + /** + * Install the app. + *

Target APIs greater than 25 must hold + * {@code }

+ * + * @param file The file. + */ + public static void installApp(final File file) { + if (!isFileExists(file)) return; + CommonBaseLibrary.getApplication().startActivity(getInstallAppIntent(file, true)); + } + + /** + * Install the app. + *

Target APIs greater than 25 must hold + * {@code }

+ * + * @param activity The activity. + * @param filePath The path of file. + * @param requestCode If >= 0, this code will be returned in + * onActivityResult() when the activity exits. + */ + public static void installApp(final Activity activity, + final String filePath, + final int requestCode) { + installApp(activity, getFileByPath(filePath), requestCode); + } + + /** + * Install the app. + *

Target APIs greater than 25 must hold + * {@code }

+ * + * @param activity The activity. + * @param file The file. + * @param requestCode If >= 0, this code will be returned in + * onActivityResult() when the activity exits. + */ + public static void installApp(final Activity activity, + final File file, + final int requestCode) { + if (!isFileExists(file)) return; + activity.startActivityForResult(getInstallAppIntent(file), requestCode); + } + + /** + * Install the app silently. + *

Without root permission must hold + * {@code android:sharedUserId="android.uid.shell"} and + * {@code }

+ * + * @param filePath The path of file. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean installAppSilent(final String filePath) { + return installAppSilent(getFileByPath(filePath), null); + } + + /** + * Install the app silently. + *

Without root permission must hold + * {@code android:sharedUserId="android.uid.shell"} and + * {@code }

+ * + * @param file The file. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean installAppSilent(final File file) { + return installAppSilent(file, null); + } + + + /** + * Install the app silently. + *

Without root permission must hold + * {@code android:sharedUserId="android.uid.shell"} and + * {@code }

+ * + * @param filePath The path of file. + * @param params The params of installation(e.g.,-r, -s). + * @return {@code true}: success
{@code false}: fail + */ + public static boolean installAppSilent(final String filePath, final String params) { + return installAppSilent(getFileByPath(filePath), params); + } + + /** + * Install the app silently. + *

Without root permission must hold + * {@code android:sharedUserId="android.uid.shell"} and + * {@code }

+ * + * @param file The file. + * @param params The params of installation(e.g.,-r, -s). + * @return {@code true}: success
{@code false}: fail + */ + public static boolean installAppSilent(final File file, final String params) { + return installAppSilent(file, params, isDeviceRooted()); + } + + /** + * Install the app silently. + *

Without root permission must hold + * {@code android:sharedUserId="android.uid.shell"} and + * {@code }

+ * + * @param file The file. + * @param params The params of installation(e.g.,-r, -s). + * @param isRooted True to use root, false otherwise. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean installAppSilent(final File file, + final String params, + final boolean isRooted) { + if (!isFileExists(file)) return false; + String filePath = '"' + file.getAbsolutePath() + '"'; + String command = "LD_LIBRARY_PATH=/vendor/lib*:/system/lib* pm install " + + (params == null ? "" : params + " ") + + filePath; + ShellUtils.CommandResult commandResult = ShellUtils.execCmd(command, isRooted); + if (commandResult.successMsg != null + && commandResult.successMsg.toLowerCase().contains("success")) { + return true; + } else { + Log.e("AppUtils", "installAppSilent successMsg: " + commandResult.successMsg + + ", errorMsg: " + commandResult.errorMsg); + return false; + } + } + + /** + * Uninstall the app. + * + * @param packageName The name of the package. + */ + public static void uninstallApp(final String packageName) { + if (isSpace(packageName)) return; + CommonBaseLibrary.getApplication().startActivity(getUninstallAppIntent(packageName, true)); + } + + /** + * Uninstall the app. + * + * @param activity The activity. + * @param packageName The name of the package. + * @param requestCode If >= 0, this code will be returned in + * onActivityResult() when the activity exits. + */ + public static void uninstallApp(final Activity activity, + final String packageName, + final int requestCode) { + if (isSpace(packageName)) return; + activity.startActivityForResult(getUninstallAppIntent(packageName), requestCode); + } + + /** + * Uninstall the app silently. + *

Without root permission must hold + * {@code android:sharedUserId="android.uid.shell"} and + * {@code }

+ * + * @param packageName The name of the package. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean uninstallAppSilent(final String packageName) { + return uninstallAppSilent(packageName, false); + } + + /** + * Uninstall the app silently. + *

Without root permission must hold + * {@code android:sharedUserId="android.uid.shell"} and + * {@code }

+ * + * @param packageName The name of the package. + * @param isKeepData Is keep the data. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean uninstallAppSilent(final String packageName, final boolean isKeepData) { + return uninstallAppSilent(packageName, isKeepData, isDeviceRooted()); + } + + /** + * Uninstall the app silently. + *

Without root permission must hold + * {@code android:sharedUserId="android.uid.shell"} and + * {@code }

+ * + * @param packageName The name of the package. + * @param isKeepData Is keep the data. + * @param isRooted True to use root, false otherwise. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean uninstallAppSilent(final String packageName, + final boolean isKeepData, + final boolean isRooted) { + if (isSpace(packageName)) return false; + String command = "LD_LIBRARY_PATH=/vendor/lib*:/system/lib* pm uninstall " + + (isKeepData ? "-k " : "") + + packageName; + ShellUtils.CommandResult commandResult = ShellUtils.execCmd(command, isRooted); + if (commandResult.successMsg != null + && commandResult.successMsg.toLowerCase().contains("success")) { + return true; + } else { + Log.e("AppUtils", "uninstallAppSilent successMsg: " + commandResult.successMsg + + ", errorMsg: " + commandResult.errorMsg); + return false; + } + } + + /** + * Return whether the app is installed. + * + * @param packageName The name of the package. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isAppInstalled(@NonNull final String packageName) { + PackageManager packageManager = CommonBaseLibrary.getApplication().getPackageManager(); + try { + return packageManager.getApplicationInfo(packageName, 0) != null; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return false; + } + } + + /** + * Return whether the application with root permission. + * + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isAppRoot() { + ShellUtils.CommandResult result = ShellUtils.execCmd("echo root", true); + if (result.result == 0) return true; + if (result.errorMsg != null) { + Log.d("AppUtils", "isAppRoot() called" + result.errorMsg); + } + return false; + } + + /** + * Return whether it is a debug application. + * + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isAppDebug() { + return isAppDebug(CommonBaseLibrary.getApplication().getPackageName()); + } + + /** + * Return whether it is a debug application. + * + * @param packageName The name of the package. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isAppDebug(final String packageName) { + if (isSpace(packageName)) return false; + try { + PackageManager pm = CommonBaseLibrary.getApplication().getPackageManager(); + ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); + return ai != null && (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return false; + } + } + + /** + * Return whether it is a system application. + * + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isAppSystem() { + return isAppSystem(CommonBaseLibrary.getApplication().getPackageName()); + } + + /** + * Return whether it is a system application. + * + * @param packageName The name of the package. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isAppSystem(final String packageName) { + if (isSpace(packageName)) return false; + try { + PackageManager pm = CommonBaseLibrary.getApplication().getPackageManager(); + ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); + return ai != null && (ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return false; + } + } + + + /** + * Return whether application is foreground. + *

Target APIs greater than 21 must hold + * {@code }

+ * + * @param packageName The name of the package. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isAppForeground(@NonNull final String packageName) { + return !isSpace(packageName) && packageName.equals(getForegroundProcessName()); + } + + /** + * Launch the application. + * + * @param packageName The name of the package. + */ + public static void launchApp(final String packageName) { + if (isSpace(packageName)) return; + CommonBaseLibrary.getApplication().startActivity(getLaunchAppIntent(packageName, true)); + } + + /** + * Launch the application. + * + * @param activity The activity. + * @param packageName The name of the package. + * @param requestCode If >= 0, this code will be returned in + * onActivityResult() when the activity exits. + */ + public static void launchApp(final Activity activity, + final String packageName, + final int requestCode) { + if (isSpace(packageName)) return; + activity.startActivityForResult(getLaunchAppIntent(packageName), requestCode); + } + + /** + * Relaunch the application. + */ + public static void relaunchApp() { + relaunchApp(false); + } + + /** + * Relaunch the application. + * + * @param isKillProcess True to kill the process, false otherwise. + */ + public static void relaunchApp(final boolean isKillProcess) { + PackageManager packageManager = CommonBaseLibrary.getApplication().getPackageManager(); + Intent intent = packageManager.getLaunchIntentForPackage(CommonBaseLibrary.getApplication().getPackageName()); + if (intent == null) return; + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + CommonBaseLibrary.getApplication().startActivity(intent); + if (!isKillProcess) return; + android.os.Process.killProcess(android.os.Process.myPid()); + System.exit(0); + } + + /** + * Launch the application's details settings. + */ + public static void launchAppDetailsSettings() { + launchAppDetailsSettings(CommonBaseLibrary.getApplication().getPackageName()); + } + + /** + * Launch the application's details settings. + * + * @param packageName The name of the package. + */ + public static void launchAppDetailsSettings(final String packageName) { + if (isSpace(packageName)) return; + Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + intent.setData(Uri.parse("package:" + packageName)); + CommonBaseLibrary.getApplication().startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + } + + + /** + * Return the application's icon. + * + * @return the application's icon + */ + public static Drawable getAppIcon() { + return getAppIcon(CommonBaseLibrary.getApplication().getPackageName()); + } + + /** + * Return the application's icon. + * + * @param packageName The name of the package. + * @return the application's icon + */ + public static Drawable getAppIcon(final String packageName) { + if (isSpace(packageName)) return null; + try { + PackageManager pm = CommonBaseLibrary.getApplication().getPackageManager(); + PackageInfo pi = pm.getPackageInfo(packageName, 0); + return pi == null ? null : pi.applicationInfo.loadIcon(pm); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Return the application's package name. + * + * @return the application's package name + */ + public static String getAppPackageName() { + return CommonBaseLibrary.getApplication().getPackageName(); + } + + /** + * Return the application's name. + * + * @return the application's name + */ + public static String getAppName() { + return getAppName(CommonBaseLibrary.getApplication().getPackageName()); + } + + /** + * Return the application's name. + * + * @param packageName The name of the package. + * @return the application's name + */ + public static String getAppName(final String packageName) { + if (isSpace(packageName)) return ""; + try { + PackageManager pm = CommonBaseLibrary.getApplication().getPackageManager(); + PackageInfo pi = pm.getPackageInfo(packageName, 0); + return pi == null ? null : pi.applicationInfo.loadLabel(pm).toString(); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return ""; + } + } + + /** + * Return the application's path. + * + * @return the application's path + */ + public static String getAppPath() { + return getAppPath(CommonBaseLibrary.getApplication().getPackageName()); + } + + /** + * Return the application's path. + * + * @param packageName The name of the package. + * @return the application's path + */ + public static String getAppPath(final String packageName) { + if (isSpace(packageName)) return ""; + try { + PackageManager pm = CommonBaseLibrary.getApplication().getPackageManager(); + PackageInfo pi = pm.getPackageInfo(packageName, 0); + return pi == null ? null : pi.applicationInfo.sourceDir; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return ""; + } + } + + /** + * Return the application's version name. + * + * @return the application's version name + */ + public static String getAppVersionName() { + return getAppVersionName(CommonBaseLibrary.getApplication().getPackageName()); + } + + /** + * Return the application's version name. + * + * @param packageName The name of the package. + * @return the application's version name + */ + public static String getAppVersionName(final String packageName) { + if (isSpace(packageName)) return ""; + try { + PackageManager pm = CommonBaseLibrary.getApplication().getPackageManager(); + PackageInfo pi = pm.getPackageInfo(packageName, 0); + return pi == null ? null : pi.versionName; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return ""; + } + } + + /** + * Return the application's version code. + * + * @return the application's version code + */ + public static int getAppVersionCode() { + return getAppVersionCode(CommonBaseLibrary.getApplication().getPackageName()); + } + + /** + * Return the application's version code. + * + * @param packageName The name of the package. + * @return the application's version code + */ + public static int getAppVersionCode(final String packageName) { + if (isSpace(packageName)) return -1; + try { + PackageManager pm = CommonBaseLibrary.getApplication().getPackageManager(); + PackageInfo pi = pm.getPackageInfo(packageName, 0); + return pi == null ? -1 : pi.versionCode; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return -1; + } + } + + /** + * Return the application's signature. + * + * @return the application's signature + */ + public static Signature[] getAppSignature() { + return getAppSignature(CommonBaseLibrary.getApplication().getPackageName()); + } + + /** + * Return the application's signature. + * + * @param packageName The name of the package. + * @return the application's signature + */ + public static Signature[] getAppSignature(final String packageName) { + if (isSpace(packageName)) return null; + try { + PackageManager pm = CommonBaseLibrary.getApplication().getPackageManager(); + @SuppressLint("PackageManagerGetSignatures") + PackageInfo pi = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); + return pi == null ? null : pi.signatures; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Return the application's signature for SHA1 value. + * + * @return the application's signature for SHA1 value + */ + public static String getAppSignatureSHA1() { + return getAppSignatureSHA1(CommonBaseLibrary.getApplication().getPackageName()); + } + + /** + * Return the application's signature for SHA1 value. + * + * @param packageName The name of the package. + * @return the application's signature for SHA1 value + */ + public static String getAppSignatureSHA1(final String packageName) { + return getAppSignatureHash(packageName, "SHA1"); + } + + /** + * Return the application's signature for SHA256 value. + * + * @return the application's signature for SHA256 value + */ + public static String getAppSignatureSHA256() { + return getAppSignatureSHA256(CommonBaseLibrary.getApplication().getPackageName()); + } + + /** + * Return the application's signature for SHA256 value. + * + * @param packageName The name of the package. + * @return the application's signature for SHA256 value + */ + public static String getAppSignatureSHA256(final String packageName) { + return getAppSignatureHash(packageName, "SHA256"); + } + + /** + * Return the application's signature for MD5 value. + * + * @return the application's signature for MD5 value + */ + public static String getAppSignatureMD5() { + return getAppSignatureMD5(CommonBaseLibrary.getApplication().getPackageName()); + } + + /** + * Return the application's signature for MD5 value. + * + * @param packageName The name of the package. + * @return the application's signature for MD5 value + */ + public static String getAppSignatureMD5(final String packageName) { + return getAppSignatureHash(packageName, "MD5"); + } + + private static String getAppSignatureHash(final String packageName, final String algorithm) { + if (isSpace(packageName)) return ""; + Signature[] signature = getAppSignature(packageName); + if (signature == null || signature.length <= 0) return ""; + return bytes2HexString(hashTemplate(signature[0].toByteArray(), algorithm)) + .replaceAll("(?<=[0-9A-F]{2})[0-9A-F]{2}", ":$0"); + } + + /** + * Return the application's information. + *
    + *
  • name of package
  • + *
  • icon
  • + *
  • name
  • + *
  • path of package
  • + *
  • version name
  • + *
  • version code
  • + *
  • is system
  • + *
+ * + * @return the application's information + */ + public static AppInfo getAppInfo() { + return getAppInfo(CommonBaseLibrary.getApplication().getPackageName()); + } + + /** + * Return the application's information. + *
    + *
  • name of package
  • + *
  • icon
  • + *
  • name
  • + *
  • path of package
  • + *
  • version name
  • + *
  • version code
  • + *
  • is system
  • + *
+ * + * @param packageName The name of the package. + * @return the application's information + */ + public static AppInfo getAppInfo(final String packageName) { + try { + PackageManager pm = CommonBaseLibrary.getApplication().getPackageManager(); + PackageInfo pi = pm.getPackageInfo(packageName, 0); + return getBean(pm, pi); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Return the applications' information. + * + * @return the applications' information + */ + public static List getAppsInfo() { + List list = new ArrayList<>(); + PackageManager pm = CommonBaseLibrary.getApplication().getPackageManager(); + List installedPackages = pm.getInstalledPackages(0); + for (PackageInfo pi : installedPackages) { + AppInfo ai = getBean(pm, pi); + if (ai == null) continue; + list.add(ai); + } + return list; + } + + /** + * Return the application's package information. + * + * @return the application's package information + */ + public static AppInfo getApkInfo(final File apkFile) { + if (apkFile == null || !apkFile.isFile() || !apkFile.exists()) return null; + return getApkInfo(apkFile.getAbsolutePath()); + } + + /** + * Return the application's package information. + * + * @return the application's package information + */ + public static AppInfo getApkInfo(final String apkFilePath) { + if (isSpace(apkFilePath)) return null; + PackageManager pm = CommonBaseLibrary.getApplication().getPackageManager(); + PackageInfo pi = pm.getPackageArchiveInfo(apkFilePath, 0); + ApplicationInfo appInfo = pi.applicationInfo; + appInfo.sourceDir = apkFilePath; + return getBean(pm, pi); + } + + private static AppInfo getBean(final PackageManager pm, final PackageInfo pi) { + if (pm == null || pi == null) return null; + ApplicationInfo ai = pi.applicationInfo; + String packageName = pi.packageName; + String name = ai.loadLabel(pm).toString(); + Drawable icon = ai.loadIcon(pm); + String packagePath = ai.sourceDir; + String versionName = pi.versionName; + int versionCode = pi.versionCode; + boolean isSystem = (ApplicationInfo.FLAG_SYSTEM & ai.flags) != 0; + return new AppInfo(packageName, name, icon, packagePath, versionName, versionCode, isSystem); + } + + /** + * The application's information. + */ + public static class AppInfo { + + private String packageName; + private String name; + private Drawable icon; + private String packagePath; + private String versionName; + private int versionCode; + private boolean isSystem; + + public Drawable getIcon() { + return icon; + } + + public void setIcon(final Drawable icon) { + this.icon = icon; + } + + public boolean isSystem() { + return isSystem; + } + + public void setSystem(final boolean isSystem) { + this.isSystem = isSystem; + } + + public String getPackageName() { + return packageName; + } + + public void setPackageName(final String packageName) { + this.packageName = packageName; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public String getPackagePath() { + return packagePath; + } + + public void setPackagePath(final String packagePath) { + this.packagePath = packagePath; + } + + public int getVersionCode() { + return versionCode; + } + + public void setVersionCode(final int versionCode) { + this.versionCode = versionCode; + } + + public String getVersionName() { + return versionName; + } + + public void setVersionName(final String versionName) { + this.versionName = versionName; + } + + public AppInfo(String packageName, String name, Drawable icon, String packagePath, + String versionName, int versionCode, boolean isSystem) { + this.setName(name); + this.setIcon(icon); + this.setPackageName(packageName); + this.setPackagePath(packagePath); + this.setVersionName(versionName); + this.setVersionCode(versionCode); + this.setSystem(isSystem); + } + + @Override + public String toString() { + return "{" + + "\n pkg name: " + getPackageName() + + "\n app icon: " + getIcon() + + "\n app name: " + getName() + + "\n app path: " + getPackagePath() + + "\n app v name: " + getVersionName() + + "\n app v code: " + getVersionCode() + + "\n is system: " + isSystem() + + "}"; + } + } + + /////////////////////////////////////////////////////////////////////////// + // other utils methods + /////////////////////////////////////////////////////////////////////////// + + private static boolean isFileExists(final File file) { + return file != null && file.exists(); + } + + private static File getFileByPath(final String filePath) { + return isSpace(filePath) ? null : new File(filePath); + } + + private static boolean isSpace(final String s) { + if (s == null) return true; + for (int i = 0, len = s.length(); i < len; ++i) { + if (!Character.isWhitespace(s.charAt(i))) { + return false; + } + } + return true; + } + + private static boolean isDeviceRooted() { + String su = "su"; + String[] locations = {"/system/bin/", "/system/xbin/", "/sbin/", "/system/sd/xbin/", + "/system/bin/failsafe/", "/data/local/xbin/", "/data/local/bin/", "/data/local/", + "/system/sbin/", "/usr/bin/", "/vendor/bin/"}; + for (String location : locations) { + if (new File(location + su).exists()) { + return true; + } + } + return false; + } + + private static final char HEX_DIGITS[] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + + private static byte[] hashTemplate(final byte[] data, final String algorithm) { + if (data == null || data.length <= 0) return null; + try { + MessageDigest md = MessageDigest.getInstance(algorithm); + md.update(data); + return md.digest(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + return null; + } + } + + private static String bytes2HexString(final byte[] bytes) { + if (bytes == null) return ""; + int len = bytes.length; + if (len <= 0) return ""; + char[] ret = new char[len << 1]; + for (int i = 0, j = 0; i < len; i++) { + ret[j++] = HEX_DIGITS[bytes[i] >> 4 & 0x0f]; + ret[j++] = HEX_DIGITS[bytes[i] & 0x0f]; + } + return new String(ret); + } + + private static Intent getInstallAppIntent(final File file) { + return getInstallAppIntent(file, false); + } + + private static Intent getInstallAppIntent(final File file, final boolean isNewTask) { + Intent intent = new Intent(Intent.ACTION_VIEW); + Uri data; + String type = "application/vnd.android.package-archive"; + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + data = Uri.fromFile(file); + } else { + String authority = CommonBaseLibrary.getApplication().getPackageName() + ".utilcode.provider"; + data = FileProvider.getUriForFile(CommonBaseLibrary.getApplication(), authority, file); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } + CommonBaseLibrary.getApplication().grantUriPermission(CommonBaseLibrary.getApplication().getPackageName(), data, Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.setDataAndType(data, type); + return isNewTask ? intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) : intent; + } + + private static Intent getUninstallAppIntent(final String packageName) { + return getUninstallAppIntent(packageName, false); + } + + private static Intent getUninstallAppIntent(final String packageName, final boolean isNewTask) { + Intent intent = new Intent(Intent.ACTION_DELETE); + intent.setData(Uri.parse("package:" + packageName)); + return isNewTask ? intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) : intent; + } + + private static Intent getLaunchAppIntent(final String packageName) { + return getLaunchAppIntent(packageName, false); + } + + private static Intent getLaunchAppIntent(final String packageName, final boolean isNewTask) { + Intent intent = CommonBaseLibrary.getApplication().getPackageManager().getLaunchIntentForPackage(packageName); + if (intent == null) return null; + return isNewTask ? intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) : intent; + } + + private static String getForegroundProcessName() { + ActivityManager am = + (ActivityManager) CommonBaseLibrary.getApplication().getSystemService(Context.ACTIVITY_SERVICE); + //noinspection ConstantConditions + List pInfo = am.getRunningAppProcesses(); + if (pInfo != null && pInfo.size() > 0) { + for (ActivityManager.RunningAppProcessInfo aInfo : pInfo) { + if (aInfo.importance + == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { + return aInfo.processName; + } + } + } + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) { + PackageManager pm = CommonBaseLibrary.getApplication().getPackageManager(); + Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); + List list = + pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); + Log.i("ProcessUtils", list.toString()); + if (list.size() <= 0) { + Log.i("ProcessUtils", + "getForegroundProcessName: noun of access to usage information."); + return ""; + } + try {// Access to usage information. + ApplicationInfo info = + pm.getApplicationInfo(CommonBaseLibrary.getApplication().getPackageName(), 0); + AppOpsManager aom = + (AppOpsManager) CommonBaseLibrary.getApplication().getSystemService(Context.APP_OPS_SERVICE); + //noinspection ConstantConditions + if (aom.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, + info.uid, + info.packageName) != AppOpsManager.MODE_ALLOWED) { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + CommonBaseLibrary.getApplication().startActivity(intent); + } + if (aom.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, + info.uid, + info.packageName) != AppOpsManager.MODE_ALLOWED) { + Log.i("ProcessUtils", + "getForegroundProcessName: refuse to device usage stats."); + return ""; + } + UsageStatsManager usageStatsManager = (UsageStatsManager) CommonBaseLibrary.getApplication() + .getSystemService(Context.USAGE_STATS_SERVICE); + List usageStatsList = null; + if (usageStatsManager != null) { + long endTime = System.currentTimeMillis(); + long beginTime = endTime - 86400000 * 7; + usageStatsList = usageStatsManager + .queryUsageStats(UsageStatsManager.INTERVAL_BEST, + beginTime, endTime); + } + if (usageStatsList == null || usageStatsList.isEmpty()) return null; + UsageStats recentStats = null; + for (UsageStats usageStats : usageStatsList) { + if (recentStats == null + || usageStats.getLastTimeUsed() > recentStats.getLastTimeUsed()) { + recentStats = usageStats; + } + } + return recentStats == null ? null : recentStats.getPackageName(); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + } + return ""; + } +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/BarUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/BarUtils.java new file mode 100644 index 0000000..30ccf39 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/BarUtils.java @@ -0,0 +1,678 @@ +package com.dahe.mylibrary.utils; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.Context; +import android.content.ContextWrapper; +import android.content.res.Resources; +import android.graphics.Color; +import android.graphics.Point; +import android.os.Build; +import android.util.Log; +import android.util.TypedValue; +import android.view.Display; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.ViewGroup; +import android.view.ViewGroup.MarginLayoutParams; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; +import androidx.annotation.RequiresPermission; +import androidx.drawerlayout.widget.DrawerLayout; + + +import com.dahe.mylibrary.CommonBaseLibrary; + +import java.lang.reflect.Method; + +import static android.Manifest.permission.EXPAND_STATUS_BAR; + +/** + * getStatusBarHeight : 获取状态栏高度(px) + * setStatusBarVisibility : 设置状态栏是否可见 + * isStatusBarVisible : 判断状态栏是否可见 + * setStatusBarLightMode : 设置状态栏是否为浅色模式 + * addMarginTopEqualStatusBarHeight : 为 view 增加 MarginTop 为状态栏高度 + * subtractMarginTopEqualStatusBarHeight: 为 view 减少 MarginTop 为状态栏高度 + * setStatusBarColor : 设置状态栏颜色 + * setStatusBarColor4Drawer : 为 DrawerLayout 设置状态栏颜色 + * getActionBarHeight : 获取 ActionBar 高度 + * setNotificationBarVisibility : 设置通知栏是否可见 + * getNavBarHeight : 获取导航栏高度 + * setNavBarVisibility : 设置导航栏是否可见 + * isNavBarVisible : 判断导航栏是否可见 + * setNavBarColor : 设置导航栏颜色 + * getNavBarColor : 获取导航栏颜色 + * isSupportNavBar : 判断是否支持导航栏 + */ +public final class BarUtils { + + /////////////////////////////////////////////////////////////////////////// + // status bar + /////////////////////////////////////////////////////////////////////////// + + private static final String TAG_STATUS_BAR = "TAG_STATUS_BAR"; + private static final String TAG_OFFSET = "TAG_OFFSET"; + private static final int KEY_OFFSET = -123; + + private BarUtils() { + throw new UnsupportedOperationException("u can't instantiate me..."); + } + + /** + * Return the status bar's height. + * + * @return the status bar's height + */ + public static int getStatusBarHeight() { + Resources resources = Resources.getSystem(); + int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android"); + return resources.getDimensionPixelSize(resourceId); + } + + /** + * Set the status bar's visibility. + * + * @param activity The activity. + * @param isVisible True to set status bar visible, false otherwise. + */ + public static void setStatusBarVisibility(@NonNull final Activity activity, + final boolean isVisible) { + setStatusBarVisibility(activity.getWindow(), isVisible); + } + + /** + * Set the status bar's visibility. + * + * @param window The window. + * @param isVisible True to set status bar visible, false otherwise. + */ + public static void setStatusBarVisibility(@NonNull final Window window, + final boolean isVisible) { + if (isVisible) { + window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + showStatusBarView(window); + addMarginTopEqualStatusBarHeight(window); + } else { + window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + hideStatusBarView(window); + subtractMarginTopEqualStatusBarHeight(window); + } + } + + /** + * Return whether the status bar is visible. + * + * @param activity The activity. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isStatusBarVisible(@NonNull final Activity activity) { + int flags = activity.getWindow().getAttributes().flags; + return (flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0; + } + + /** + * Set the status bar's light mode. + * + * @param activity The activity. + * @param isLightMode True to set status bar light mode, false otherwise. + */ + public static void setStatusBarLightMode(@NonNull final Activity activity, + final boolean isLightMode) { + setStatusBarLightMode(activity.getWindow(), isLightMode); + } + + /** + * Set the status bar's light mode. + * + * @param window The window. + * @param isLightMode True to set status bar light mode, false otherwise. + */ + public static void setStatusBarLightMode(@NonNull final Window window, + final boolean isLightMode) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + View decorView = window.getDecorView(); + if (decorView != null) { + int vis = decorView.getSystemUiVisibility(); + if (isLightMode) { + vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + } else { + vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + } + decorView.setSystemUiVisibility(vis); + } + } + } + + /** + * Is the status bar light mode. + * + * @param activity The activity. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isStatusBarLightMode(@NonNull final Activity activity) { + return isStatusBarLightMode(activity.getWindow()); + } + + /** + * Is the status bar light mode. + * + * @param window The window. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isStatusBarLightMode(@NonNull final Window window) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + View decorView = window.getDecorView(); + if (decorView != null) { + int vis = decorView.getSystemUiVisibility(); + return (vis & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0; + } + } + return false; + } + + /** + * Add the top margin size equals status bar's height for view. + * + * @param view The view. + */ + public static void addMarginTopEqualStatusBarHeight(@NonNull View view) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return; + view.setTag(TAG_OFFSET); + Object haveSetOffset = view.getTag(KEY_OFFSET); + if (haveSetOffset != null && (Boolean) haveSetOffset) return; + MarginLayoutParams layoutParams = (MarginLayoutParams) view.getLayoutParams(); + layoutParams.setMargins(layoutParams.leftMargin, + layoutParams.topMargin + getStatusBarHeight(), + layoutParams.rightMargin, + layoutParams.bottomMargin); + view.setTag(KEY_OFFSET, true); + } + + /** + * Subtract the top margin size equals status bar's height for view. + * + * @param view The view. + */ + public static void subtractMarginTopEqualStatusBarHeight(@NonNull View view) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return; + Object haveSetOffset = view.getTag(KEY_OFFSET); + if (haveSetOffset == null || !(Boolean) haveSetOffset) return; + MarginLayoutParams layoutParams = (MarginLayoutParams) view.getLayoutParams(); + layoutParams.setMargins(layoutParams.leftMargin, + layoutParams.topMargin - getStatusBarHeight(), + layoutParams.rightMargin, + layoutParams.bottomMargin); + view.setTag(KEY_OFFSET, false); + } + + private static void addMarginTopEqualStatusBarHeight(final Window window) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return; + View withTag = window.getDecorView().findViewWithTag(TAG_OFFSET); + if (withTag == null) return; + addMarginTopEqualStatusBarHeight(withTag); + } + + private static void subtractMarginTopEqualStatusBarHeight(final Window window) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return; + View withTag = window.getDecorView().findViewWithTag(TAG_OFFSET); + if (withTag == null) return; + subtractMarginTopEqualStatusBarHeight(withTag); + } + + /** + * Set the status bar's color. + * + * @param activity The activity. + * @param color The status bar's color. + */ + public static View setStatusBarColor(@NonNull final Activity activity, + @ColorInt final int color) { + return setStatusBarColor(activity, color, false); + } + + /** + * Set the status bar's color. + * + * @param activity The activity. + * @param color The status bar's color. + * @param isDecor True to add fake status bar in DecorView, + * false to add fake status bar in ContentView. + */ + public static View setStatusBarColor(@NonNull final Activity activity, + @ColorInt final int color, + final boolean isDecor) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return null; + transparentStatusBar(activity); + return applyStatusBarColor(activity, color, isDecor); + } + + /** + * Set the status bar's color. + * + * @param fakeStatusBar The fake status bar view. + * @param color The status bar's color. + */ + public static void setStatusBarColor(@NonNull final View fakeStatusBar, + @ColorInt final int color) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return; + Activity activity = getActivityByView(fakeStatusBar); + if (activity == null) return; + transparentStatusBar(activity); + fakeStatusBar.setVisibility(View.VISIBLE); + ViewGroup.LayoutParams layoutParams = fakeStatusBar.getLayoutParams(); + layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT; + layoutParams.height = getStatusBarHeight(); + fakeStatusBar.setBackgroundColor(color); + } + + /** + * Set the custom status bar. + * + * @param fakeStatusBar The fake status bar view. + */ + public static void setStatusBarCustom(@NonNull final View fakeStatusBar) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return; + Activity activity = getActivityByView(fakeStatusBar); + if (activity == null) return; + transparentStatusBar(activity); + fakeStatusBar.setVisibility(View.VISIBLE); + ViewGroup.LayoutParams layoutParams = fakeStatusBar.getLayoutParams(); + if (layoutParams == null) { + layoutParams = new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + getStatusBarHeight() + ); + fakeStatusBar.setLayoutParams(layoutParams); + } else { + layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT; + layoutParams.height = getStatusBarHeight(); + } + } + + /** + * Set the status bar's color for DrawerLayout. + *

DrawLayout must add {@code android:fitsSystemWindows="true"}

+ * + * @param drawer The DrawLayout. + * @param fakeStatusBar The fake status bar view. + * @param color The status bar's color. + */ + public static void setStatusBarColor4Drawer(@NonNull final DrawerLayout drawer, + @NonNull final View fakeStatusBar, + @ColorInt final int color) { + setStatusBarColor4Drawer(drawer, fakeStatusBar, color, false); + } + + /** + * Set the status bar's color for DrawerLayout. + *

DrawLayout must add {@code android:fitsSystemWindows="true"}

+ * + * @param drawer The DrawLayout. + * @param fakeStatusBar The fake status bar view. + * @param color The status bar's color. + * @param isTop True to set DrawerLayout at the top layer, false otherwise. + */ + public static void setStatusBarColor4Drawer(@NonNull final DrawerLayout drawer, + @NonNull final View fakeStatusBar, + @ColorInt final int color, + final boolean isTop) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return; + Activity activity = getActivityByView(fakeStatusBar); + if (activity == null) return; + transparentStatusBar(activity); + drawer.setFitsSystemWindows(false); + setStatusBarColor(fakeStatusBar, color); + for (int i = 0, count = drawer.getChildCount(); i < count; i++) { + drawer.getChildAt(i).setFitsSystemWindows(false); + } + if (isTop) { + hideStatusBarView(activity); + } else { + setStatusBarColor(activity, color, false); + } + } + + private static View applyStatusBarColor(final Activity activity, + final int color, + boolean isDecor) { + ViewGroup parent = isDecor ? + (ViewGroup) activity.getWindow().getDecorView() : + (ViewGroup) activity.findViewById(android.R.id.content); + View fakeStatusBarView = parent.findViewWithTag(TAG_STATUS_BAR); + if (fakeStatusBarView != null) { + if (fakeStatusBarView.getVisibility() == View.GONE) { + fakeStatusBarView.setVisibility(View.VISIBLE); + } + fakeStatusBarView.setBackgroundColor(color); + } else { + fakeStatusBarView = createStatusBarView(activity, color); + parent.addView(fakeStatusBarView); + } + return fakeStatusBarView; + } + + private static void hideStatusBarView(final Activity activity) { + hideStatusBarView(activity.getWindow()); + } + + private static void hideStatusBarView(final Window window) { + ViewGroup decorView = (ViewGroup) window.getDecorView(); + View fakeStatusBarView = decorView.findViewWithTag(TAG_STATUS_BAR); + if (fakeStatusBarView == null) return; + fakeStatusBarView.setVisibility(View.GONE); + } + + private static void showStatusBarView(final Window window) { + ViewGroup decorView = (ViewGroup) window.getDecorView(); + View fakeStatusBarView = decorView.findViewWithTag(TAG_STATUS_BAR); + if (fakeStatusBarView == null) return; + fakeStatusBarView.setVisibility(View.VISIBLE); + } + + private static View createStatusBarView(final Activity activity, + final int color) { + View statusBarView = new View(activity); + statusBarView.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight())); + statusBarView.setBackgroundColor(color); + statusBarView.setTag(TAG_STATUS_BAR); + return statusBarView; + } + + private static void transparentStatusBar(final Activity activity) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return; + Window window = activity.getWindow(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + int option = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + window.getDecorView().setSystemUiVisibility(option); + window.setStatusBarColor(Color.TRANSPARENT); + } else { + window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + } + } + + /////////////////////////////////////////////////////////////////////////// + // action bar + /////////////////////////////////////////////////////////////////////////// + + /** + * Return the action bar's height. + * + * @return the action bar's height + */ + public static int getActionBarHeight() { + TypedValue tv = new TypedValue(); + if (CommonBaseLibrary.getApplication().getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) { + return TypedValue.complexToDimensionPixelSize( + tv.data, CommonBaseLibrary.getApplication().getResources().getDisplayMetrics() + ); + } + return 0; + } + + /////////////////////////////////////////////////////////////////////////// + // notification bar + /////////////////////////////////////////////////////////////////////////// + + /** + * Set the notification bar's visibility. + *

Must hold {@code }

+ * + * @param isVisible True to set notification bar visible, false otherwise. + */ + @RequiresPermission(EXPAND_STATUS_BAR) + public static void setNotificationBarVisibility(final boolean isVisible) { + String methodName; + if (isVisible) { + methodName = (Build.VERSION.SDK_INT <= 16) ? "expand" : "expandNotificationsPanel"; + } else { + methodName = (Build.VERSION.SDK_INT <= 16) ? "collapse" : "collapsePanels"; + } + invokePanels(methodName); + } + + private static void invokePanels(final String methodName) { + try { + @SuppressLint("WrongConstant") + Object service = CommonBaseLibrary.getApplication().getSystemService("statusbar"); + @SuppressLint("PrivateApi") + Class statusBarManager = Class.forName("android.app.StatusBarManager"); + Method expand = statusBarManager.getMethod(methodName); + expand.invoke(service); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /////////////////////////////////////////////////////////////////////////// + // navigation bar + /////////////////////////////////////////////////////////////////////////// + + /** + * Return the navigation bar's height. + * + * @return the navigation bar's height + */ + public static int getNavBarHeight() { + Resources res = Resources.getSystem(); + int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android"); + if (resourceId != 0) { + return res.getDimensionPixelSize(resourceId); + } else { + return 0; + } + } + + /** + * Set the navigation bar's visibility. + * + * @param activity The activity. + * @param isVisible True to set navigation bar visible, false otherwise. + */ + public static void setNavBarVisibility(@NonNull final Activity activity, boolean isVisible) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return; + setNavBarVisibility(activity.getWindow(), isVisible); + + } + + /** + * Set the navigation bar's visibility. + * + * @param window The window. + * @param isVisible True to set navigation bar visible, false otherwise. + */ + public static void setNavBarVisibility(@NonNull final Window window, boolean isVisible) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return; + final ViewGroup decorView = (ViewGroup) window.getDecorView(); + for (int i = 0, count = decorView.getChildCount(); i < count; i++) { + final View child = decorView.getChildAt(i); + final int id = child.getId(); + if (id != View.NO_ID) { + String resourceEntryName = CommonBaseLibrary.getApplication() + .getResources() + .getResourceEntryName(id); + if ("navigationBarBackground".equals(resourceEntryName)) { + child.setVisibility(isVisible ? View.VISIBLE : View.INVISIBLE); + } + } + } + final int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; + if (isVisible) { + decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() & ~uiOptions); + } else { + decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() | uiOptions); + } + } + + /** + * Return whether the navigation bar visible. + *

Call it in onWindowFocusChanged will get right result.

+ * + * @param activity The activity. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isNavBarVisible(@NonNull final Activity activity) { + return isNavBarVisible(activity.getWindow()); + } + + + + /** + * 判断是否显示了导航栏 + * (说明这里的context 一定要是activity的context 否则类型转换失败) + * + * @param context + * @return + */ +// public static boolean isShowNavBar(Context context) { +// if (null == context) { +// node_return false; +// } +// /** +// * 获取应用区域高度 +// */ +// Rect outRect1 = new Rect(); +// try { +// ((Activity) context).getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect1); +// } catch (ClassCastException e) { +// e.printStackTrace(); +// node_return false; +// } +// int activityHeight = outRect1.height(); +// /** +// * 获取状态栏高度 +// */ +// int statuBarHeight = WindowDispaly.getStatusBarHeight(); +// /** +// * 屏幕物理高度 减去 状态栏高度 +// */ +// int remainHeight = WindowDispaly.getRealHeight() - statuBarHeight; +// /** +// * 剩余高度跟应用区域高度相等 说明导航栏没有显示 否则相反 +// */ +// if (activityHeight == remainHeight) { +// node_return false; +// } else { +// node_return true; +// } +// +// } + + /** + * Return whether the navigation bar visible. + *

Call it in onWindowFocusChanged will get right result.

+ * + * @param window The window. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isNavBarVisible(@NonNull final Window window) { + boolean isVisible = false; + ViewGroup decorView = (ViewGroup) window.getDecorView(); + for (int i = 0, count = decorView.getChildCount(); i < count; i++) { + final View child = decorView.getChildAt(i); + final int id = child.getId(); + if (id != View.NO_ID) { + String resourceEntryName = CommonBaseLibrary.getApplication() + .getResources() + .getResourceEntryName(id); + if ("navigationBarBackground".equals(resourceEntryName) + && child.getVisibility() == View.VISIBLE) { + isVisible = true; + break; + } + } + } + if (isVisible) { + int visibility = decorView.getSystemUiVisibility(); + isVisible = (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0; + } + return isVisible; + } + + /** + * Set the navigation bar's color. + * + * @param activity The activity. + * @param color The navigation bar's color. + */ + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) + public static void setNavBarColor(@NonNull final Activity activity, @ColorInt final int color) { + setNavBarColor(activity.getWindow(), color); + } + + /** + * Set the navigation bar's color. + * + * @param window The window. + * @param color The navigation bar's color. + */ + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) + public static void setNavBarColor(@NonNull final Window window, @ColorInt final int color) { + window.setNavigationBarColor(color); + } + + /** + * Return the color of navigation bar. + * + * @param activity The activity. + * @return the color of navigation bar + */ + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) + public static int getNavBarColor(@NonNull final Activity activity) { + return getNavBarColor(activity.getWindow()); + } + + /** + * Return the color of navigation bar. + * + * @param window The window. + * @return the color of navigation bar + */ + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) + public static int getNavBarColor(@NonNull final Window window) { + return window.getNavigationBarColor(); + } + + /** + * Return whether the navigation bar visible. + * + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isSupportNavBar() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + WindowManager wm = (WindowManager) CommonBaseLibrary.getApplication().getSystemService(Context.WINDOW_SERVICE); + if (wm == null) return false; + Display display = wm.getDefaultDisplay(); + Point size = new Point(); + Point realSize = new Point(); + display.getSize(size); + display.getRealSize(realSize); + return realSize.y != size.y || realSize.x != size.x; + } + boolean menu = ViewConfiguration.get(CommonBaseLibrary.getApplication()).hasPermanentMenuKey(); + boolean back = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK); + return !menu && !back; + } + + private static Activity getActivityByView(@NonNull final View view) { + Context context = view.getContext(); + while (context instanceof ContextWrapper) { + if (context instanceof Activity) { + return (Activity) context; + } + context = ((ContextWrapper) context).getBaseContext(); + } + Log.e("BarUtils", "the view's Context is not an Activity."); + return null; + } +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/Base64Utils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/Base64Utils.java new file mode 100644 index 0000000..8278fda --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/Base64Utils.java @@ -0,0 +1,13 @@ +package com.dahe.mylibrary.utils; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.Base64; + +public class Base64Utils { + + public static Bitmap asdf(String imageBase64){ + byte[] decodedString = Base64.decode(imageBase64, Base64.DEFAULT); + return BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/BaseSPUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/BaseSPUtils.java new file mode 100644 index 0000000..9450e59 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/BaseSPUtils.java @@ -0,0 +1,193 @@ +package com.dahe.mylibrary.utils; + +import android.content.Context; +import android.content.SharedPreferences; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; + +/** + * 轻量级数据存储工具类 + * + * @author Administrator + */ +public class BaseSPUtils { + /** + * 保存在手机里面的文件名 + */ + public static final String FILE_NAME = "sp_data"; + public static final String USER_INFO_KEY = "user_info_key"; + public static final String NET_SERVICE_TEST = "net_service_test"; + public static final String SEARRH_CACHE = "search_cache"; + public static final String NAVI_PH_EDIT_CACHE = "navi_ph_edit_cache"; + public static final String FIRST_OPEN = "first_open"; + public static final String KEY_PRIVACY_AGREEMENT = "privacy_agreement"; + + /** + * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法 + * + * @param context + * @param key + * @param object + */ + public static void put(Context context, String key, Object object) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + + SharedPreferencesCompat.apply(editor); + } + + /** + * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值 + * + * @param context + * @param key + * @param defaultObject + * @return + */ + public static Object get(Context context, String key, Object defaultObject) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); + + if (defaultObject instanceof String) { + return sp.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sp.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sp.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sp.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sp.getLong(key, (Long) defaultObject); + } + + return null; + } + + /** + * 移除某个key值已经对应的值 + * + * @param context + * @param key + */ + public static void remove(Context context, String key) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.remove(key); + SharedPreferencesCompat.apply(editor); + } + + /** + * 清除所有数据 + * + * @param context + */ + public static void clear(Context context) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.clear(); + SharedPreferencesCompat.apply(editor); + } + + /** + * 查询某个key是否已经存在 + * + * @param context + * @param key + * @return + */ + public static boolean contains(Context context, String key) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); + return sp.contains(key); + } + + /** + * 返回所有的键值对 + * + * @param context + * @return + */ + public static Map getAll(Context context) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); + return sp.getAll(); + } + + /** + * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类 + * + * @author zhy + */ + private static class SharedPreferencesCompat { + private static final Method sApplyMethod = findApplyMethod(); + + /** + * 反射查找apply的方法 + * + * @return + */ + @SuppressWarnings( + {"unchecked", "rawtypes"}) + private static Method findApplyMethod() { + try { + Class clz = SharedPreferences.Editor.class; + return clz.getMethod("apply"); + } catch (NoSuchMethodException e) { + } + + return null; + } + + /** + * 如果找到则使用apply执行,否则使用commit + * + * @param editor + */ + public static void apply(SharedPreferences.Editor editor) { + try { + if (sApplyMethod != null) { + sApplyMethod.invoke(editor); + return; + } + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) { + } catch (InvocationTargetException e) { + } + editor.commit(); + } + } + + /*****---------------------------------------------***/ + /** + * 是否含有用户信息 + * + * @param context + * @return + */ + public static boolean hasUserInfo(Context context) { + return contains(context, USER_INFO_KEY); + } + + /** + * 清除用户信息 + * + * @param context + * @return + */ + public static void cleanUserInfo(Context context) { + remove(context, USER_INFO_KEY); + } + +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/BaseUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/BaseUtils.java new file mode 100644 index 0000000..da2d6de --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/BaseUtils.java @@ -0,0 +1,243 @@ +package com.dahe.mylibrary.utils; + +import android.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.provider.ContactsContract; +import android.text.TextUtils; +import android.view.View; +import android.view.inputmethod.InputMethodManager; + +import androidx.appcompat.app.AppCompatActivity; + +import com.dahe.mylibrary.R; +import com.shehuan.nicedialog.BaseNiceDialog; +import com.shehuan.nicedialog.NiceDialog; +import com.shehuan.nicedialog.ViewConvertListener; +import com.shehuan.nicedialog.ViewHolder; + +import java.util.Locale; + +public class BaseUtils { + /** + * 验证手机格式 + */ + public static boolean isMobileNO(String mobiles) { + String telRegex = "[1][3456789]\\d{9}"; + // "[1]"代表第1位为数字1,"[358]"代表第二位可以为3、5、8中的一个,"\\d{9}"代表后面是可以是0~9的数字,有9位。 + if (TextUtils.isEmpty(mobiles)) return false; + else return mobiles.matches(telRegex); + } + + + /** + * 获取语言 + * + * @param context + * @return + */ + public static int getLanguage(Context context) { + Locale curLocale = getLocale(context); + String language = curLocale.getLanguage(); + String country = curLocale.getCountry(); + if (language.equals(Locale.CHINA.getLanguage())) { + //0是简体中文,1是繁体中文 + return country.equals(Locale.SIMPLIFIED_CHINESE.getCountry()) ? 0 : 1; + } else if (language.equals(Locale.ENGLISH.getLanguage())) { + //英语 + return 2; + } else if (language.equals("th")) { + //泰文 + return 3; + } else if (language.equals(Locale.KOREAN.getLanguage())) { + //韩文 + return 4; + } else if (language.equals("vi")) { + //越南语 + return 5; + } else if (language.equals(Locale.JAPAN.getLanguage())) { + //日语 + return 6; + } else if (language.equals("in")) { + //印尼语 + return 7; + } else { + return 2; + } + } + + //获取Locale + private static Locale getLocale(Context context) { + Locale locale; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + locale = context.getResources().getConfiguration().getLocales().get(0); + } else { + locale = context.getResources().getConfiguration().locale; + } + return locale; + } + + + /** + * 拨打电话(直接拨打电话) + * @param phoneNum 电话号码 + */ + public static void callPhone(AppCompatActivity context , String phoneNum){ + + NiceDialog.init() + .setLayoutId(R.layout.dialog_phone) + .setConvertListener(new ViewConvertListener() { + @Override + protected void convertView(ViewHolder viewHolder, BaseNiceDialog baseNiceDialog) { + viewHolder.setText(R.id.message, phoneNum); + viewHolder.setOnClickListener(R.id.ok, new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(Intent.ACTION_CALL); + Uri data = Uri.parse("tel:" + phoneNum); + intent.setData(data); + context.startActivity(intent); + baseNiceDialog.dismiss(); + } + }); + viewHolder.setOnClickListener(R.id.cancel, new View.OnClickListener() { + @Override + public void onClick(View v) { + baseNiceDialog.dismiss(); + } + }); + } + }) + .setWidth(260).show(context.getSupportFragmentManager()); + + } + + /** + * 获取VersionCode + * + * @param context + * @return + */ + public static String geVersionCode(Context context) { + try { + PackageInfo packageInfo = context.getPackageManager() + .getPackageInfo(context.getPackageName(), 0); + return packageInfo.versionName; + } catch (Exception e) { + return "1.0.0"; + } + } + + /** + * 跳转qq + * + * @param context + * @return + */ + public static String goToQQ(Context context, String qqNumber) { + try { + context.getPackageManager().getApplicationInfo("com.tencent.mobileqq", + PackageManager.GET_UNINSTALLED_PACKAGES); + context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("mqqwpa://im/chat?chat_type=wpa&uin=" + qqNumber + "&version=1"))); + } catch (PackageManager.NameNotFoundException e) { + return "客服为qq在线,联系客服请先安装qq"; + } + return ""; + } + + /** + * 跳转手机通讯录 选择联系人 并返回联系人信息 + * + * @param context + * @param uri + * @return + */ + public static String[] getPhoneContacts(Context context, Uri uri) { + String[] contact = new String[2]; + ContentResolver cr = context.getContentResolver(); + Cursor cursor = cr.query(uri, null, null, null, null); + if (cursor != null && cursor.getCount() != 0) { + cursor.moveToFirst(); + int nameFieldColumnIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); + contact[0] = cursor.getString(nameFieldColumnIndex); + String ContactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); + Cursor phone = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, + ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + ContactId, null, null); + if (phone != null && phone.getCount() != 0) { + phone.moveToFirst(); + contact[1] = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).trim().replace(" ", "").toString(); + } else { + contact[1] = ""; + } + phone.close(); + cursor.close(); + } else { + return null; + } + return contact; + } + + /** + * 根据手机的分辨率从 dp 的单位 转成为 px(像素) + */ + public static int dip2px(Context context, float dpValue) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (dpValue * scale + 0.5f); + } + + /** + * 根据手机的分辨率从 px(像素) 的单位 转成为 dp + */ + public static int px2dip(Context context, float pxValue) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (pxValue / scale + 0.5f); + } + + /** + * 将sp值转换为px值,保证文字大小不变 + * + * @param spValue + * @param spValue (DisplayMetrics类中属性scaledDensity) + * @return + */ + public static int sp2px(Context context, float spValue) { + final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; + return (int) (spValue * fontScale + 0.5f); + } + + /** + * 强制隐藏输入法键盘 + * + * @param context Context + * @param view EditText + */ + public static void hideInput(Context context, View view) { + InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0); + } + + /** + * 隐藏软键盘(只适用于Activity,不适用于Fragment) + */ + public static void hideSoftKeyboard(Activity activity) { + View view = activity.getCurrentFocus(); + if (view != null) { + InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE); + inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); + } + } + + //view为接受软键盘输入的视图,SHOW_FORCED表示强制显示 + public static void hideSoftKeyboard(Activity activity, View view) { + InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(view, InputMethodManager.SHOW_FORCED); + imm.hideSoftInputFromWindow(view.getWindowToken(), 0); //强制隐藏键盘 + } + +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/CNPinyinIndex.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/CNPinyinIndex.java new file mode 100644 index 0000000..d55d146 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/CNPinyinIndex.java @@ -0,0 +1,76 @@ +package com.dahe.mylibrary.utils; + +import java.io.UnsupportedEncodingException; + +public class CNPinyinIndex { + + + //自动获取汉子的首字母 + static final int GB_SP_DIFF = 160; + // 存放国标一级汉字不同读音的起始区位码 + static final int[] secPosValueList = {1601, 1637, 1833, 2078, 2274, 2302, + 2433, 2594, 2787, 3106, 3212, 3472, 3635, 3722, 3730, 3858, 4027, + 4086, 4390, 4558, 4684, 4925, 5249, 5600}; + // 存放国标一级汉字不同读音的起始区位码对应读音 + static final char[] firstLetter = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'w', 'x', + 'y', 'z'}; + + + + public static String getSpells(String characters) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < characters.length(); i++) { + + char ch = characters.charAt(i); + if ((ch >> 7) == 0) { + // 判断是否为汉字,如果左移7为为0就不是汉字,否则是汉字 + } else { + char spell = getFirstLetter(ch); + buffer.append(String.valueOf(spell)); + } + } + return buffer.toString(); + } + + // 获取一个汉字的首字母 + public static Character getFirstLetter(char ch) { + + byte[] uniCode = null; + try { + uniCode = String.valueOf(ch).getBytes("GBK"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return null; + } + if (uniCode[0] < 128 && uniCode[0] > 0) { // 非汉字 + return null; + } else { + return convert(uniCode); + } + } + + /** + * 获取一个汉字的拼音首字母。 GB码两个字节分别减去160,转换成10进制码组合就可以得到区位码 + * 例如汉字“你”的GB码是0xC4/0xE3,分别减去0xA0(160)就是0x24/0x43 + * 0x24转成10进制就是36,0x43是67,那么它的区位码就是3667,在对照表中读音为‘n’ + */ + static char convert(byte[] bytes) { + char result = '-'; + int secPosValue = 0; + int i; + for (i = 0; i < bytes.length; i++) { + bytes[i] -= GB_SP_DIFF; + } + secPosValue = bytes[0] * 100 + bytes[1]; + for (i = 0; i < 23; i++) { + if (secPosValue >= secPosValueList[i] + && secPosValue < secPosValueList[i + 1]) { + result = firstLetter[i]; + break; + } + } + return result; + } + +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/ConvertUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/ConvertUtils.java new file mode 100644 index 0000000..a45c471 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/ConvertUtils.java @@ -0,0 +1,645 @@ +package com.dahe.mylibrary.utils; + + +import android.annotation.SuppressLint; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.PixelFormat; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.view.View; + + +import com.dahe.mylibrary.CommonBaseLibrary; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +/** + * bytes2Bits, bits2Bytes : bytes 与 bits 互转 + * bytes2Chars, chars2Bytes : bytes 与 chars 互转 + * bytes2HexString, hexString2Bytes : bytes 与 hexString 互转 + * memorySize2Byte, byte2MemorySize : 以 unit 为单位的内存大小与字节数互转 + * byte2FitMemorySize : 字节数转合适内存大小 + * timeSpan2Millis, millis2TimeSpan : 以 unit 为单位的时间长度与毫秒时间戳互转 + * millis2FitTimeSpan : 毫秒时间戳转合适时间长度 + * input2OutputStream, output2InputStream : inputStream 与 outputStream 互转 + * inputStream2Bytes, bytes2InputStream : inputStream 与 bytes 互转 + * outputStream2Bytes, bytes2OutputStream : outputStream 与 bytes 互转 + * inputStream2String, string2InputStream : inputStream 与 string 按编码互转 + * outputStream2String, string2OutputStream: outputStream 与 string 按编码互转 + * bitmap2Bytes, bytes2Bitmap : bitmap 与 bytes 互转 + * drawable2Bitmap, bitmap2Drawable : drawable 与 bitmap 互转 + * drawable2Bytes, bytes2Drawable : drawable 与 bytes 互转 + * view2Bitmap : view 转 Bitmap + * dp2px, px2dp : dp 与 px 互转 + * sp2px, px2sp : sp 与 px 互转 + */ +public final class ConvertUtils { + + private ConvertUtils() { + throw new UnsupportedOperationException("u can't instantiate me..."); + } + + private static final char hexDigits[] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + + /** + * Bytes to bits. + * + * @param bytes The bytes. + * @return bits + */ + public static String bytes2Bits(final byte[] bytes) { + if (bytes == null || bytes.length == 0) return ""; + StringBuilder sb = new StringBuilder(); + for (byte aByte : bytes) { + for (int j = 7; j >= 0; --j) { + sb.append(((aByte >> j) & 0x01) == 0 ? '0' : '1'); + } + } + return sb.toString(); + } + + /** + * Bits to bytes. + * + * @param bits The bits. + * @return bytes + */ + public static byte[] bits2Bytes(String bits) { + int lenMod = bits.length() % 8; + int byteLen = bits.length() / 8; + // add "0" until length to 8 times + if (lenMod != 0) { + for (int i = lenMod; i < 8; i++) { + bits = "0" + bits; + } + byteLen++; + } + byte[] bytes = new byte[byteLen]; + for (int i = 0; i < byteLen; ++i) { + for (int j = 0; j < 8; ++j) { + bytes[i] <<= 1; + bytes[i] |= bits.charAt(i * 8 + j) - '0'; + } + } + return bytes; + } + + /** + * Bytes to chars. + * + * @param bytes The bytes. + * @return chars + */ + public static char[] bytes2Chars(final byte[] bytes) { + if (bytes == null) return null; + int len = bytes.length; + if (len <= 0) return null; + char[] chars = new char[len]; + for (int i = 0; i < len; i++) { + chars[i] = (char) (bytes[i] & 0xff); + } + return chars; + } + + /** + * Chars to bytes. + * + * @param chars The chars. + * @return bytes + */ + public static byte[] chars2Bytes(final char[] chars) { + if (chars == null || chars.length <= 0) return null; + int len = chars.length; + byte[] bytes = new byte[len]; + for (int i = 0; i < len; i++) { + bytes[i] = (byte) (chars[i]); + } + return bytes; + } + + /** + * Bytes to hex string. + *

e.g. bytes2HexString(new byte[] { 0, (byte) 0xa8 }) returns "00A8"

+ * + * @param bytes The bytes. + * @return hex string + */ + public static String bytes2HexString(final byte[] bytes) { + if (bytes == null) return ""; + int len = bytes.length; + if (len <= 0) return ""; + char[] ret = new char[len << 1]; + for (int i = 0, j = 0; i < len; i++) { + ret[j++] = hexDigits[bytes[i] >> 4 & 0x0f]; + ret[j++] = hexDigits[bytes[i] & 0x0f]; + } + return new String(ret); + } + + /** + * Hex string to bytes. + *

e.g. hexString2Bytes("00A8") returns { 0, (byte) 0xA8 }

+ * + * @param hexString The hex string. + * @return the bytes + */ + public static byte[] hexString2Bytes(String hexString) { + if (isSpace(hexString)) return null; + int len = hexString.length(); + if (len % 2 != 0) { + hexString = "0" + hexString; + len = len + 1; + } + char[] hexBytes = hexString.toUpperCase().toCharArray(); + byte[] ret = new byte[len >> 1]; + for (int i = 0; i < len; i += 2) { + ret[i >> 1] = (byte) (hex2Int(hexBytes[i]) << 4 | hex2Int(hexBytes[i + 1])); + } + return ret; + } + + private static int hex2Int(final char hexChar) { + if (hexChar >= '0' && hexChar <= '9') { + return hexChar - '0'; + } else if (hexChar >= 'A' && hexChar <= 'F') { + return hexChar - 'A' + 10; + } else { + throw new IllegalArgumentException(); + } + } + + /** + * Size of memory in unit to size of byte. + * + * @param memorySize Size of memory. + * @param unit The unit of memory size. + *
    + *
  • {@link MemoryConstants#BYTE}
  • + *
  • {@link MemoryConstants#KB}
  • + *
  • {@link MemoryConstants#MB}
  • + *
  • {@link MemoryConstants#GB}
  • + *
+ * @return size of byte + */ + public static long memorySize2Byte(final long memorySize, + @MemoryConstants.Unit final int unit) { + if (memorySize < 0) return -1; + return memorySize * unit; + } + + /** + * Size of byte to size of memory in unit. + * + * @param byteSize Size of byte. + * @param unit The unit of memory size. + *
    + *
  • {@link MemoryConstants#BYTE}
  • + *
  • {@link MemoryConstants#KB}
  • + *
  • {@link MemoryConstants#MB}
  • + *
  • {@link MemoryConstants#GB}
  • + *
+ * @return size of memory in unit + */ + public static double byte2MemorySize(final long byteSize, + @MemoryConstants.Unit final int unit) { + if (byteSize < 0) return -1; + return (double) byteSize / unit; + } + + /** + * Size of byte to fit size of memory. + *

to three decimal places

+ * + * @param byteSize Size of byte. + * @return fit size of memory + */ + @SuppressLint("DefaultLocale") + public static String byte2FitMemorySize(final long byteSize) { + if (byteSize < 0) { + return "shouldn't be less than zero!"; + } else if (byteSize < MemoryConstants.KB) { + return String.format("%.3fB", (double) byteSize); + } else if (byteSize < MemoryConstants.MB) { + return String.format("%.3fKB", (double) byteSize / MemoryConstants.KB); + } else if (byteSize < MemoryConstants.GB) { + return String.format("%.3fMB", (double) byteSize / MemoryConstants.MB); + } else { + return String.format("%.3fGB", (double) byteSize / MemoryConstants.GB); + } + } + + /** + * Time span in unit to milliseconds. + * + * @param timeSpan The time span. + * @param unit The unit of time span. + *
    + *
  • {@link TimeConstants#MSEC}
  • + *
  • {@link TimeConstants#SEC }
  • + *
  • {@link TimeConstants#MIN }
  • + *
  • {@link TimeConstants#HOUR}
  • + *
  • {@link TimeConstants#DAY }
  • + *
+ * @return milliseconds + */ + public static long timeSpan2Millis(final long timeSpan, @TimeConstants.Unit final int unit) { + return timeSpan * unit; + } + + /** + * Milliseconds to time span in unit. + * + * @param millis The milliseconds. + * @param unit The unit of time span. + *
    + *
  • {@link TimeConstants#MSEC}
  • + *
  • {@link TimeConstants#SEC }
  • + *
  • {@link TimeConstants#MIN }
  • + *
  • {@link TimeConstants#HOUR}
  • + *
  • {@link TimeConstants#DAY }
  • + *
+ * @return time span in unit + */ + public static long millis2TimeSpan(final long millis, @TimeConstants.Unit final int unit) { + return millis / unit; + } + + /** + * Milliseconds to fit time span. + * + * @param millis The milliseconds. + *

millis <= 0, node_return null

+ * @param precision The precision of time span. + *
    + *
  • precision = 0, node_return null
  • + *
  • precision = 1, node_return 天
  • + *
  • precision = 2, node_return 天, 小时
  • + *
  • precision = 3, node_return 天, 小时, 分钟
  • + *
  • precision = 4, node_return 天, 小时, 分钟, 秒
  • + *
  • precision >= 5,node_return 天, 小时, 分钟, 秒, 毫秒
  • + *
+ * @return fit time span + */ + @SuppressLint("DefaultLocale") + public static String millis2FitTimeSpan(long millis, int precision) { + if (millis <= 0 || precision <= 0) return null; + StringBuilder sb = new StringBuilder(); + String[] units = {"天", "小时", "分钟", "秒", "毫秒"}; + int[] unitLen = {86400000, 3600000, 60000, 1000, 1}; + precision = Math.min(precision, 5); + for (int i = 0; i < precision; i++) { + if (millis >= unitLen[i]) { + long mode = millis / unitLen[i]; + millis -= mode * unitLen[i]; + sb.append(mode).append(units[i]); + } + } + return sb.toString(); + } + + /** + * Input stream to output stream. + * + * @param is The input stream. + * @return output stream + */ + public static ByteArrayOutputStream input2OutputStream(final InputStream is) { + if (is == null) return null; + try { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + byte[] b = new byte[MemoryConstants.KB]; + int len; + while ((len = is.read(b, 0, MemoryConstants.KB)) != -1) { + os.write(b, 0, len); + } + return os; + } catch (IOException e) { + e.printStackTrace(); + return null; + } finally { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * Output stream to input stream. + * + * @param out The output stream. + * @return input stream + */ + public ByteArrayInputStream output2InputStream(final OutputStream out) { + if (out == null) return null; + return new ByteArrayInputStream(((ByteArrayOutputStream) out).toByteArray()); + } + + /** + * Input stream to bytes. + * + * @param is The input stream. + * @return bytes + */ + public static byte[] inputStream2Bytes(final InputStream is) { + if (is == null) return null; + return input2OutputStream(is).toByteArray(); + } + + /** + * Bytes to input stream. + * + * @param bytes The bytes. + * @return input stream + */ + public static InputStream bytes2InputStream(final byte[] bytes) { + if (bytes == null || bytes.length <= 0) return null; + return new ByteArrayInputStream(bytes); + } + + /** + * Output stream to bytes. + * + * @param out The output stream. + * @return bytes + */ + public static byte[] outputStream2Bytes(final OutputStream out) { + if (out == null) return null; + return ((ByteArrayOutputStream) out).toByteArray(); + } + + /** + * Bytes to output stream. + * + * @param bytes The bytes. + * @return output stream + */ + public static OutputStream bytes2OutputStream(final byte[] bytes) { + if (bytes == null || bytes.length <= 0) return null; + ByteArrayOutputStream os = null; + try { + os = new ByteArrayOutputStream(); + os.write(bytes); + return os; + } catch (IOException e) { + e.printStackTrace(); + return null; + } finally { + try { + if (os != null) { + os.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * Input stream to string. + * + * @param is The input stream. + * @param charsetName The name of charset. + * @return string + */ + public static String inputStream2String(final InputStream is, final String charsetName) { + if (is == null || isSpace(charsetName)) return ""; + try { + return new String(inputStream2Bytes(is), charsetName); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return ""; + } + } + + /** + * String to input stream. + * + * @param string The string. + * @param charsetName The name of charset. + * @return input stream + */ + public static InputStream string2InputStream(final String string, final String charsetName) { + if (string == null || isSpace(charsetName)) return null; + try { + return new ByteArrayInputStream(string.getBytes(charsetName)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Output stream to string. + * + * @param out The output stream. + * @param charsetName The name of charset. + * @return string + */ + public static String outputStream2String(final OutputStream out, final String charsetName) { + if (out == null || isSpace(charsetName)) return ""; + try { + return new String(outputStream2Bytes(out), charsetName); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return ""; + } + } + + /** + * String to output stream. + * + * @param string The string. + * @param charsetName The name of charset. + * @return output stream + */ + public static OutputStream string2OutputStream(final String string, final String charsetName) { + if (string == null || isSpace(charsetName)) return null; + try { + return bytes2OutputStream(string.getBytes(charsetName)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Bitmap to bytes. + * + * @param bitmap The bitmap. + * @param format The format of bitmap. + * @return bytes + */ + public static byte[] bitmap2Bytes(final Bitmap bitmap, final Bitmap.CompressFormat format) { + if (bitmap == null) return null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + bitmap.compress(format, 100, baos); + return baos.toByteArray(); + } + + /** + * Bytes to bitmap. + * + * @param bytes The bytes. + * @return bitmap + */ + public static Bitmap bytes2Bitmap(final byte[] bytes) { + return (bytes == null || bytes.length == 0) + ? null + : BitmapFactory.decodeByteArray(bytes, 0, bytes.length); + } + + /** + * Drawable to bitmap. + * + * @param drawable The drawable. + * @return bitmap + */ + public static Bitmap drawable2Bitmap(final Drawable drawable) { + if (drawable instanceof BitmapDrawable) { + BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; + if (bitmapDrawable.getBitmap() != null) { + return bitmapDrawable.getBitmap(); + } + } + Bitmap bitmap; + if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) { + bitmap = Bitmap.createBitmap(1, 1, + drawable.getOpacity() != PixelFormat.OPAQUE + ? Bitmap.Config.ARGB_8888 + : Bitmap.Config.RGB_565); + } else { + 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, canvas.getWidth(), canvas.getHeight()); + drawable.draw(canvas); + return bitmap; + } + + /** + * Bitmap to drawable. + * + * @param bitmap The bitmap. + * @return drawable + */ + public static Drawable bitmap2Drawable(final Bitmap bitmap) { + return bitmap == null ? null : new BitmapDrawable(CommonBaseLibrary.getApplication().getResources(), bitmap); + } + + /** + * Drawable to bytes. + * + * @param drawable The drawable. + * @param format The format of bitmap. + * @return bytes + */ + public static byte[] drawable2Bytes(final Drawable drawable, + final Bitmap.CompressFormat format) { + return drawable == null ? null : bitmap2Bytes(drawable2Bitmap(drawable), format); + } + + /** + * Bytes to drawable. + * + * @param bytes The bytes. + * @return drawable + */ + public static Drawable bytes2Drawable(final byte[] bytes) { + return bytes == null ? null : bitmap2Drawable(bytes2Bitmap(bytes)); + } + + /** + * View to bitmap. + * + * @param view The view. + * @return bitmap + */ + public static Bitmap view2Bitmap(final View view) { + if (view == null) return null; + Bitmap ret = + Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(ret); + Drawable bgDrawable = view.getBackground(); + if (bgDrawable != null) { + bgDrawable.draw(canvas); + } else { + canvas.drawColor(Color.WHITE); + } + view.draw(canvas); + return ret; + } + + /** + * Value of dp to value of px. + * + * @param dpValue The value of dp. + * @return value of px + */ + public static int dp2px(final float dpValue) { + final float scale = Resources.getSystem().getDisplayMetrics().density; + return (int) (dpValue * scale + 0.5f); + } + + /** + * Value of px to value of dp. + * + * @param pxValue The value of px. + * @return value of dp + */ + public static int px2dp(final float pxValue) { + final float scale = Resources.getSystem().getDisplayMetrics().density; + return (int) (pxValue / scale + 0.5f); + } + + /** + * Value of sp to value of px. + * + * @param spValue The value of sp. + * @return value of px + */ + public static int sp2px(final float spValue) { + final float fontScale = Resources.getSystem().getDisplayMetrics().scaledDensity; + return (int) (spValue * fontScale + 0.5f); + } + + /** + * Value of px to value of sp. + * + * @param pxValue The value of px. + * @return value of sp + */ + public static int px2sp(final float pxValue) { + final float fontScale = Resources.getSystem().getDisplayMetrics().scaledDensity; + return (int) (pxValue / fontScale + 0.5f); + } + + /////////////////////////////////////////////////////////////////////////// + // other utils methods + /////////////////////////////////////////////////////////////////////////// + + private static boolean isSpace(final String s) { + if (s == null) return true; + for (int i = 0, len = s.length(); i < len; ++i) { + if (!Character.isWhitespace(s.charAt(i))) { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/CountDownTimerUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/CountDownTimerUtils.java new file mode 100644 index 0000000..faf18ab --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/CountDownTimerUtils.java @@ -0,0 +1,38 @@ +package com.dahe.mylibrary.utils; + +import android.os.CountDownTimer; +import android.widget.TextView; + +public class CountDownTimerUtils extends CountDownTimer { + + private TextView mTextView; + /** + * @param millisInFuture The number of millis in the future from the call + * to {@link #start()} until the countdown is done and {@link #onFinish()} + * is called. + * @param countDownInterval The interval along the way to receive + * {@link #onTick(long)} callbacks. + */ + public CountDownTimerUtils(TextView textView, long millisInFuture, long countDownInterval) { + super(millisInFuture, countDownInterval); + this.mTextView = textView; + } + + @Override + public void onTick(long millisUntilFinished) { + mTextView.setClickable(false); //设置不可点击 + mTextView.setText(millisUntilFinished / 1000 + "秒后重新发送"); //设置倒计时时间 +// mTextView.setBackgroundResource(R.drawable.bg_identify_code_press); //设置按钮为灰色,这时是不能点击的 +// SpannableString spannableString = new SpannableString(mTextView.getText().toString()); //获取按钮上的文字 +// ForegroundColorSpan span = new ForegroundColorSpan(Color.RED); +// spannableString.setSpan(span, 0, 2, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);//将倒计时的时间设置为红色 +// mTextView.setText(spannableString); + } + + @Override + public void onFinish() { + mTextView.setText("获取验证码"); + mTextView.setClickable(true);//重新获得点击 +// mTextView.setBackgroundResource(R.drawable.bg_identify_code_normal); //还原背景色 + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/CrashHandler.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/CrashHandler.java new file mode 100644 index 0000000..928d308 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/CrashHandler.java @@ -0,0 +1,243 @@ +package com.dahe.mylibrary.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Environment; +import android.os.Looper; +import android.os.SystemClock; +import android.util.Log; +import android.widget.Toast; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.lang.reflect.Field; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import static android.os.Environment.DIRECTORY_ALARMS; + +/** + *

全局捕获异常

+ *
+ * 当程序发生Uncaught异常的时候,有该类来接管程序,并记录错误日志 + * + */ +@SuppressLint("SimpleDateFormat") +public class CrashHandler implements Thread.UncaughtExceptionHandler { + + public static String TAG = "MyCrash"; + // 系统默认的UncaughtException处理类 + private Thread.UncaughtExceptionHandler mDefaultHandler; + + private static CrashHandler instance = new CrashHandler(); + private Context mContext; + + // 用来存储设备信息和异常信息 + private Map infos = new HashMap(); + + // 用于格式化日期,作为日志文件名的一部分 + private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + /** 保证只有一个CrashHandler实例 */ + private CrashHandler() { + } + + /** 获取CrashHandler实例 ,单例模式 */ + public static CrashHandler getInstance() { + return instance; + } + + /** + * 初始化 + * + * @param context + */ + public void init(Context context) { + mContext = context; + // 获取系统默认的UncaughtException处理器 + mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); + // 设置该CrashHandler为程序的默认处理器 + Thread.setDefaultUncaughtExceptionHandler(this); + FileUtil.removeFileByTime(getGlobalpath()); +// autoClear(5); + } + + /** + * 当UncaughtException发生时会转入该函数来处理 + */ + @Override + public void uncaughtException(Thread thread, Throwable ex) { + if (!handleException(ex) && mDefaultHandler != null) { + // 如果用户没有处理则让系统默认的异常处理器来处理 + mDefaultHandler.uncaughtException(thread, ex); + } else { + SystemClock.sleep(3000); + // 退出程序 + android.os.Process.killProcess(android.os.Process.myPid()); + System.exit(1); + } + } + + /** + * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. + * + * @param ex + * @return true:如果处理了该异常信息; 否则返回false. + */ + private boolean handleException(Throwable ex) { + if (ex == null) + return false; + try { + // 使用Toast来显示异常信息 + new Thread() { + + @Override + public void run() { + Looper.prepare(); + Toast.makeText(mContext, "很抱歉,程序出现异常,即将重启.", + Toast.LENGTH_LONG).show(); + Looper.loop(); + } + }.start(); + // 收集设备参数信息 + collectDeviceInfo(mContext); + // 保存日志文件 + saveCrashInfoFile(ex); + SystemClock.sleep(3000); + } catch (Exception e) { + e.printStackTrace(); + } + + return true; + } + + /** + * 收集设备参数信息 + * + * @param ctx + */ + public void collectDeviceInfo(Context ctx) { + try { + PackageManager pm = ctx.getPackageManager(); + PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), + PackageManager.GET_ACTIVITIES); + if (pi != null) { + String versionName = pi.versionName + ""; + String versionCode = pi.versionCode + ""; + infos.put("versionName", versionName); + infos.put("versionCode", versionCode); + } + } catch (PackageManager.NameNotFoundException e) { + Log.e(TAG, "an error occured when collect package info", e); + } + Field[] fields = Build.class.getDeclaredFields(); + for (Field field : fields) { + try { + field.setAccessible(true); + infos.put(field.getName(), field.get(null).toString()); + } catch (Exception e) { + Log.e(TAG, "an error occured when collect crash info", e); + } + } + } + + /** + * 保存错误信息到文件中 + * @param ex + * @return 返回文件名称,便于将文件传送到服务器 + * @throws Exception + */ + private String saveCrashInfoFile(Throwable ex) throws Exception { + StringBuffer sb = new StringBuffer(); + try { + SimpleDateFormat sDateFormat = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); + String date = sDateFormat.format(new java.util.Date()); + sb.append("\r\n" + date + "\n"); + for (Map.Entry entry : infos.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + sb.append(key + "=" + value + "\n"); + } + + Writer writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + Throwable cause = ex.getCause(); + while (cause != null) { + cause.printStackTrace(printWriter); + cause = cause.getCause(); + } + printWriter.flush(); + printWriter.close(); + String result = writer.toString(); + sb.append(result); + + String fileName = writeFile(sb.toString()); + return fileName; + } catch (Exception e) { + Log.e(TAG, "an error occured while writing file...", e); + sb.append("an error occured while writing file...\r\n"); + writeFile(sb.toString()); + } + return null; + } + + private String writeFile(String sb) throws Exception { + String time = formatter.format(new Date()); + String fileName = "crash-" + time + ".log"; +// if (FileUtil.hasSdcard()) { + String path = getGlobalpath(); + File dir = new File(path); + if (!dir.exists()) + dir.mkdirs(); + + String filePath = path + fileName; + File txtFile = new File(filePath); + if (!txtFile.exists()) + txtFile.createNewFile(); + + FileOutputStream fos = new FileOutputStream(txtFile, true); + fos.write(sb.getBytes()); + fos.flush(); + fos.close(); +// } + return fileName; + } + + public static String getGlobalpath() { + return Environment.getExternalStorageDirectory().getAbsolutePath() + + File.separator + "crash" + File.separator; + } + + public static void setTag(String tag) { + TAG = tag; + } + + /** + * 文件删除 + * @param day 文件保存天数 + */ +// public void autoClear(final int autoClearDay) { +// FileUtil.delete(getGlobalpath(), new FilenameFilter() { +// +// @Override +// public boolean accept(File file, String filename) { +// String s = FileUtil.getFileNameWithoutExtension(filename); +// int day = autoClearDay < 0 ? autoClearDay : -1 * autoClearDay; +// String date = "crash-" + DateUtil.getOtherDay(day); +// return date.compareTo(s) >= 0; +// } +// }); +// } +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/FileUtil.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/FileUtil.java new file mode 100644 index 0000000..1eda86f --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/FileUtil.java @@ -0,0 +1,89 @@ +package com.dahe.mylibrary.utils; + +import android.util.Log; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + +import static com.dahe.mylibrary.utils.CrashHandler.TAG; + +public class FileUtil { + + + + + //移除文件,获取文件时间与当前时间对比,我这时间定位5天,删除五天前的文件 + public static void removeFileByTime(String dirPath) { + //获取目录下所有文件 + List allFile = getDirAllFile(new File(dirPath)); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + //获取当前时间 + Date end = new Date(System.currentTimeMillis()); + try { + end = dateFormat.parse(dateFormat.format(new Date(System.currentTimeMillis()))); + } catch (Exception e){ + Log.d(TAG, "dataformat exeption e " + e.toString()); + } + Log.d(TAG, "getNeedRemoveFile dirPath = " +dirPath); + for (File file : allFile) {//ComDef + try { + //文件时间减去当前时间 + Date start = dateFormat.parse(dateFormat.format(new Date(file.lastModified()))); + long diff = end.getTime() - start.getTime();//这样得到的差值是微秒级别 + long days = diff / (1000 * 60 * 60 * 24); +// if(ComDef.LOGMAXKEEPTIME <= days){ + if(5 <= days){ + deleteFile(file); + } + + } catch (Exception e){ + Log.d(TAG, "dataformat exeption e " + e.toString()); + } + } + } + + //删除文件夹及文件夹下所有文件 + public static void deleteFile(File file) { + if (file.isDirectory()) { + File[] files = file.listFiles(); + for (int i = 0; i < files.length; i++) { + File f = files[i]; + deleteFile(f); + } + file.delete(); + } else if (file.exists()) { + file.delete(); + } + } + + //获取指定目录下一级文件 + public static List getDirAllFile(File file) { + List fileList = new ArrayList<>(); + File[] fileArray = file.listFiles(); + if(fileArray == null) + return fileList; + for (File f : fileArray) { + fileList.add(f); + } + fileSortByTime(fileList); + return fileList; + } + + + //对文件进行时间排序 + public static void fileSortByTime(List fileList) { + Collections.sort(fileList, new Comparator() { + public int compare(File p1, File p2) { + if (p1.lastModified() < p2.lastModified()) { + return -1; + } + return 1; + } + }); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/ImageLoader.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/ImageLoader.java new file mode 100644 index 0000000..1890f38 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/ImageLoader.java @@ -0,0 +1,204 @@ +package com.dahe.mylibrary.utils; + +import android.content.Context; +import android.widget.ImageView; + +import androidx.core.content.ContextCompat; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.MultiTransformation; +import com.bumptech.glide.load.resource.bitmap.CenterCrop; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.dahe.mylibrary.weight.GlideCircleWithBorder; + +/** + * Created by Administrator on 2017/11/27 0027. + * 图片加载工具类 + */ + +public class ImageLoader { + public static ImageLoader mInstance = null; + + public static ImageLoader getInstance() { + if (null == mInstance) { + synchronized (ImageLoader.class) { + if (null == mInstance) { + mInstance = new ImageLoader(); + } + } + } + return mInstance; + } + + /** + * 普通的加载图片 带占位图 + * + * @param context + * @param url + * @param imageView + * @param multiTransformation 同时设置scaleType在设置圆角或者圆形 + */ + public void loadingImage(Context context, final Object url, final ImageView imageView, MultiTransformation multiTransformation, int placeholder) { + RequestOptions requestOptions = new RequestOptions(); + if (null != context) { + if (placeholder != -1) + requestOptions = requestOptions.placeholder(placeholder).error(placeholder); + if (null != multiTransformation) + requestOptions = requestOptions.transform(multiTransformation); + Glide.with(context).load(url).apply(requestOptions).into(imageView); + } + } + + /** + * 普通的加载图片 + * + * @param context + * @param url + * @param imageView + */ + public void loadingImage(Context context, final Object url, final ImageView imageView) { + loadingImage(context, url, imageView, null, -1); + } + + /** + * 普通的加载图片 带展位图 + * + * @param context + * @param url + * @param imageView + */ + public void loadImage(Context context, final Object url, final ImageView imageView, RequestOptions requestOptions, int placeholder) { + if (null != context) { + if (placeholder != -1) + requestOptions = requestOptions.placeholder(placeholder).error(placeholder); + Glide.with(context).load(url).centerCrop().apply(requestOptions).into(imageView); + } + } + + /** + * 普通的加载图片 不带占位图的 + * + * @param context + * @param url + * @param imageView + */ + @Deprecated + public void loadImage(Context context, final Object url, final ImageView imageView) { + loadImage(context, url, imageView, -1); + } + + /** + * 普通的加载图片 不带占位图的 + * + * @param context + * @param url + * @param imageView + */ + public void loadImage(Context context, final Object url, final ImageView imageView, int placeholder) { + RequestOptions requestOptions = new RequestOptions(); + loadImage(context, url, imageView, requestOptions, placeholder); + } + + /** + * 加载圆形图片 + * + * @param context + * @param url + * @param imageView + */ + public void loadCircleImage(Context context, Object url, ImageView imageView, int placeholder) { + if (null != context) { + loadImage(context, url, imageView, RequestOptions.circleCropTransform(), placeholder); + } + } + + /** + * 加载圆形图片 + * + * @param context + * @param url + * @param imageView + */ + public void loadCircleImage(Context context, Object url, ImageView imageView) { + if (null != context) { + loadCircleImage(context, url, imageView, -1); + } + } + + /** + * 加载圆角图片 + * + * @param context + * @param url + * @param round + * @param imageView + */ + public void loadRoundImage(Context context, Object url, int round, ImageView imageView, int placeholder) { + if (null != context) { + RequestOptions requestOptions = RequestOptions.fitCenterTransform().transform(new CenterCrop(), new RoundedCorners(round)); +// RequestOptions requestOptions = new RequestOptions(); +// requestOptions.transform(new GlideRoundTransform(context, round)); + loadImage(context, url, imageView, requestOptions, placeholder); + } + } + + /** + * 加载圆角图片 + * + * @param context + * @param url + * @param round + * @param imageView + */ + public void loadRoundImage(Context context, Object url, int round, ImageView imageView) { + if (null != context) { + loadRoundImage(context, url, round, imageView, -1); + } + } + + /** + * 加载圆形带圆环图片 + * + * @param context + * @param url + * @param imageView + */ + public void loadCircleWithBorderImage(Context context, Object url, int borderWidth, int borderColor, ImageView imageView, int placeholder) { + if (null != context) { + RequestOptions requestOptions = new RequestOptions(); + requestOptions.transform(new GlideCircleWithBorder(context, borderWidth, ContextCompat.getColor(context, borderColor))); + loadImage(context, url, imageView, requestOptions, placeholder); + } + } + + + /** + * 加载圆形带圆环图片 + * + * @param context + * @param url + * @param imageView + */ + public void loadCircleWithBorderImage(Context context, Object url,RequestOptions requestOptions, int borderWidth, int borderColor, ImageView imageView, int placeholder) { + if (null != context) { + requestOptions.transform(new GlideCircleWithBorder(context, borderWidth, ContextCompat.getColor(context, borderColor))); + loadImage(context, url, imageView, requestOptions, placeholder); + } + } + + /** + * 加载圆形带圆环图片 + * + * @param context + * @param url + * @param imageView + */ + public void loadCircleWithBorderImage(Context context, Object url, int borderWidth, int borderColor, ImageView imageView) { + if (null != context) { + loadCircleWithBorderImage(context, url, borderWidth, borderColor, imageView, -1); + } + } + + +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/LocationUtil.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/LocationUtil.java new file mode 100644 index 0000000..6a2d88b --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/LocationUtil.java @@ -0,0 +1,325 @@ +package com.dahe.mylibrary.utils; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.location.LocationProvider; +import android.os.Bundle; +import android.util.Log; + +import androidx.core.app.ActivityCompat; + +import java.io.IOException; +import java.util.List; + +import io.reactivex.rxjava3.annotations.Nullable; +import pub.devrel.easypermissions.EasyPermissions; + +public class LocationUtil { + private static OnResponseListener responseListener; + private static LocationUtil locationUtil; + + private LocationManager locationManager; + private Location currentBestLocation; + private NetworkListener networkListener; + private GPSLocationListener gpsListener; + + private LocationUtil() { + } + + /** + * 定位模式 + */ + public enum Mode { + NETWORK, //网络定位 + GPS, //GPS定位 + AUTO //自动定位,使用网络或GPS定位 + } + + + public static final int NO_PERMISSION = 1; //没权限 + public static final int GPS_CLOSE = 2; //GPS是关闭的 + public static final int UNAVAILABLE = 3; //不可用 + + /** + * 请求定位 + */ + public static void requestLocation(Context context, Mode mode, OnResponseListener onResponseListener) { + LocationUtil.responseListener = onResponseListener; + if (EasyPermissions.hasPermissions(context, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION)) { + Log.i("lj", "获取定位权限,开始定位"); + //开始定位 + locationUtil = new LocationUtil(); + locationUtil.startLocation(context, mode); + } else { + Log.i("lj", "没有定位权限,定位失败"); + String provider = mode == Mode.GPS ? LocationManager.GPS_PROVIDER : LocationManager.NETWORK_PROVIDER; + onResponseListener.onErrorResponse(provider, NO_PERMISSION); + } + } + + /** + * 开始定位 + */ + private void startLocation(Context context, Mode mode) { + locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { + switch (mode) { + case NETWORK: + if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { + Log.i("lj", "网络定位"); + networkListener = new NetworkListener(); + locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 500, 0.1f, networkListener); + } else { + responseListener.onErrorResponse(LocationManager.NETWORK_PROVIDER, UNAVAILABLE); + } + break; + case GPS: + if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { + Log.i("lj","GPS定位"); + gpsListener = new GPSLocationListener(); + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000 * 2, 0.1f, gpsListener); + } else { + responseListener.onErrorResponse(LocationManager.GPS_PROVIDER, GPS_CLOSE); + } + + break; + case AUTO: + if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { + Log.i("lj","自动定位选择网络定位"); + networkListener = new NetworkListener(); + locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 500, 0.1f, networkListener); + } else if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { + Log.i("lj","自动定位选择gps"); + gpsListener = new GPSLocationListener(); + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000 * 2, 0.1f, gpsListener); + } else { + responseListener.onErrorResponse(LocationManager.NETWORK_PROVIDER, UNAVAILABLE); + } + + break; + default: + + break; + } + } else { + Log.i("lj","无权限"); + } + } + + /** + * 停止定位 + */ + public static void stopLocation() { + if (locationUtil == null) { + Log.i("lj","locationUtil is null"); + return; + } + if (locationUtil.networkListener != null) { + locationUtil.locationManager.removeUpdates(locationUtil.networkListener); + } + if (locationUtil.gpsListener != null) { + locationUtil.locationManager.removeUpdates(locationUtil.gpsListener); + } +// L.i("停止定位"); + } + + private class GPSLocationListener implements LocationListener { + @Override + public void onLocationChanged(Location location) { +// L.i("onLocationChanged"); + if (location != null) { +// L.i("GPS定位成功"); +// L.i("GPS定位耗时:" + ((System.currentTimeMillis() - l) / 1000) + "秒"); + boolean isBetter = isBetterLocation(location, currentBestLocation); + if (isBetter) { + currentBestLocation = location; + } + double latitude = currentBestLocation.getLatitude(); //纬度 + double longitude = currentBestLocation.getLongitude(); //经度 + responseListener.onSuccessResponse(latitude, longitude); + } else { +// L.i("location is null"); + } + } + + @SuppressLint("MissingPermission") + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { +// L.i("onStatusChanged:" + status); + if (status == LocationProvider.OUT_OF_SERVICE || status == LocationProvider.TEMPORARILY_UNAVAILABLE) { +// L.i("GPS定位失败"); + //如果之前没有开启过网络定位,自动切换到网络定位 + if (networkListener == null) { + //开启网络定位 + networkListener = new NetworkListener(); + locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, networkListener); + } + } + } + + @Override + public void onProviderEnabled(String provider) { +// L.i("onProviderEnabled"); + } + + @Override + public void onProviderDisabled(String provider) { +// L.i("onProviderDisabled"); + } + } + + private class NetworkListener implements LocationListener { + @Override + public void onLocationChanged(Location location) { + if (location != null) { +// L.i("网络定位成功"); + + boolean isBetter = isBetterLocation(location, currentBestLocation); + if (isBetter) { + currentBestLocation = location; + } + double latitude = currentBestLocation.getLatitude(); //纬度 + double longitude = currentBestLocation.getLongitude(); //经度 + responseListener.onSuccessResponse(latitude, longitude); + + } + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + if (status == LocationProvider.OUT_OF_SERVICE || status == LocationProvider.TEMPORARILY_UNAVAILABLE) { +// Log.i("网络定位失败"); + responseListener.onErrorResponse(LocationManager.NETWORK_PROVIDER, UNAVAILABLE); + } + } + + @Override + public void onProviderEnabled(String provider) { +// L.e("可用"); + } + + @Override + public void onProviderDisabled(String provider) { +// L.e("不可用"); + } + } + + private static final int TWO_MINUTES = 1000 * 60 * 2; + + /** + * 比较最新获取到的位置是否比当前最好的位置更好 + * + * @param location 最新获得的位置 + * @param currentBestLocation 当前获取到的最好的位置 + * @return 最新获取的位置比当前最好的位置更好则返回true + */ + private boolean isBetterLocation(Location location, Location currentBestLocation) { + if (currentBestLocation == null) { + // A new locationUtil is always better than no locationUtil + return true; + } + + //实时性 + // Check whether the new locationUtil fix is newer or older + long timeDelta = location.getTime() - currentBestLocation.getTime(); + boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; //最新位置比当前位置晚两分钟定位 + boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;//最新位置比当前位置早两分钟定位 + boolean isNewer = timeDelta > 0; + + // If it's been more than two minutes since the current locationUtil, use the new locationUtil + // because the user has likely moved + if (isSignificantlyNewer) { + return true; + // If the new locationUtil is more than two minutes older, it must be worse + } else if (isSignificantlyOlder) { + return false; + } + + //精确性 + // Check whether the new locationUtil fix is more or less accurate + //locationUtil.getAccuracy()值越小越精确 + int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); + boolean isLessAccurate = accuracyDelta > 0; //最新的位置不如当前的精确 + boolean isMoreAccurate = accuracyDelta < 0; //最新的位置比当前的精确 + //最新的位置不如当前的精确,但是相差在一定范围之内 + boolean isSignificantlyLessAccurate = accuracyDelta > 200; + + // Check if the old and new locationUtil are from the same provider + boolean isFromSameProvider = isSameProvider(location.getProvider(), + currentBestLocation.getProvider()); + + // Determine locationUtil quality using a combination of timeliness and accuracy + if (isMoreAccurate) { + return true; + } else if (isNewer && !isLessAccurate) { + return true; + } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { + return true; + } + return false; + } + + /** + * Checks whether two providers are the same + */ + private boolean isSameProvider(String provider1, String provider2) { + if (provider1 == null) { + return provider2 == null; + } + return provider1.equals(provider2); + } + + public interface OnResponseListener { + /** + * 定位成功 + * + * @param latitude 纬度 + * @param longitude 经度 + */ + void onSuccessResponse(double latitude, double longitude); + + /** + * 定位失败 + * + * @param provider provider + * @param status 失败码 + */ + void onErrorResponse(String provider, int status); + } + + /** + * 获取地址 + * + * @param context Context + * @param latitude 纬度 + * @param longitude 经度 + * @return Address + */ + public static @Nullable + Address getAddress(Context context, double latitude, double longitude) { + Geocoder geocoder = new Geocoder(context); + try { + List
list = geocoder.getFromLocation(latitude, longitude, 3); + if (list.size() > 0) { + Address address = list.get(0); +// Log.i("省:" + address.getAdminArea()); +// Log.i("市:" + address.getLocality()); +// Log.i("县/区:" + address.getSubLocality()); + return address; + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/MD5Utils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/MD5Utils.java new file mode 100644 index 0000000..4c2afac --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/MD5Utils.java @@ -0,0 +1,60 @@ +package com.dahe.mylibrary.utils; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.security.MessageDigest; + +public class MD5Utils { + + private static final int BUFFERSIZE = 8196; + private static final String ALGORITHM = "MD5"; + private static final String CHARSET = "UTF-8"; + + public MD5Utils() { + } + + public static String md5(String input) { + return md5(input, CHARSET); + } + + private static String md5(String input, String charsetName) { + try { + MessageDigest md5 = MessageDigest.getInstance(ALGORITHM); + byte md5Bytes[] = md5.digest(input.getBytes(charsetName)); + return StringUtils.byte2hex(md5Bytes); + } catch (Exception e) { + e.printStackTrace(); + } + return input; + } + + public static String md5file(File filename) { + BufferedInputStream bufferedInputStream = null; + MessageDigest md; + try { + bufferedInputStream = new BufferedInputStream(new FileInputStream(filename), BUFFERSIZE); + md = MessageDigest.getInstance(ALGORITHM); + byte[] buffer = new byte[BUFFERSIZE]; + int i = 0; + while ((i = bufferedInputStream.read(buffer)) != -1) { + md.update(buffer, 0, i); + } + return StringUtils.byte2hex(md.digest()); + } catch (Exception e) { + e.printStackTrace(); + return null; + } finally { + try { + bufferedInputStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public static String md5reverse(String md5) { + return ""; + } + +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/MemoryConstants.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/MemoryConstants.java new file mode 100644 index 0000000..7566d70 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/MemoryConstants.java @@ -0,0 +1,28 @@ +package com.dahe.mylibrary.utils; + + +import androidx.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + *
+ *     author: Blankj
+ *     blog  : http://blankj.com
+ *     time  : 2017/03/13
+ *     desc  : constants of memory
+ * 
+ */ +public final class MemoryConstants { + + public static final int BYTE = 1; + public static final int KB = 1024; + public static final int MB = 1048576; + public static final int GB = 1073741824; + + @IntDef({BYTE, KB, MB, GB}) + @Retention(RetentionPolicy.SOURCE) + public @interface Unit { + } +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/PatternUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/PatternUtils.java new file mode 100644 index 0000000..f3ec6fa --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/PatternUtils.java @@ -0,0 +1,28 @@ +package com.dahe.mylibrary.utils; + +import java.util.regex.Pattern; + +public class PatternUtils { + + + /** + * 正则表达式:验证密码(包含大小写,数字,特殊字符,6-12位) + */ +// public static final String REGEX_PASSWORD = "^(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*,\\.])[0-9a-zA-Z!@#$%^&*,\\\\.]{6,12}$"; + public static final String REGEX_PASSWORD = "^(?=.*[0-9])(?=.*[a-z])(?=.*[!@#$%^&*,\\.])[0-9a-zA-Z!@#$%^&*,\\\\.]{6,12}$"; + public static final String REGEX_WORD = "^[A-Za-z]+$"; + + /** + * 校验密码 + * + * @param password + * @return 校验通过返回true,否则返回false + */ + public static boolean isPassword(String password) { + return Pattern.matches(REGEX_PASSWORD, password); + } + + public static boolean isLetter(String password){ + return Pattern.matches(REGEX_WORD, password); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/PhoneFormatCheckUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/PhoneFormatCheckUtils.java new file mode 100644 index 0000000..2ab5ba1 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/PhoneFormatCheckUtils.java @@ -0,0 +1,55 @@ +package com.dahe.mylibrary.utils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +public class PhoneFormatCheckUtils { + + /** + * 大陆号码或香港号码均可 + */ + public static boolean isPhoneLegal(String str) throws PatternSyntaxException { + return isChinaPhoneLegal(str) || isHKPhoneLegal(str); + } + + /** + * 大陆手机号码11位数,匹配格式:前三位固定格式+后8位任意数 + * 此方法中前三位格式有: + * 13+任意数 + * 145,147,149 + * 15+除4的任意数(不要写^4,这样的话字母也会被认为是正确的) + * 166 + * 17+3,5,6,7,8 + * 18+任意数 + * 198,199 + */ + public static boolean isChinaPhoneLegal(String str) throws PatternSyntaxException { + // ^ 匹配输入字符串开始的位置 + // \d 匹配一个或多个数字,其中 \ 要转义,所以是 \\d + // $ 匹配输入字符串结尾的位置 + String regExp = "^((13[0-9])|(14[5,7,9])|(15[0-3,5-9])|(166)|(17[3,5,6,7,8])" + + "|(18[0-9])|(19[8,9]))\\d{8}$"; + Pattern p = Pattern.compile(regExp); + Matcher m = p.matcher(str); + return m.matches(); + } + + /** + * 香港手机号码8位数,5|6|8|9开头+7位任意数 + */ + public static boolean isHKPhoneLegal(String str) throws PatternSyntaxException { + // ^ 匹配输入字符串开始的位置 + // \d 匹配一个或多个数字,其中 \ 要转义,所以是 \\d + // $ 匹配输入字符串结尾的位置 + String regExp = "^(5|6|8|9)\\d{7}$"; + Pattern p = Pattern.compile(regExp); + Matcher m = p.matcher(str); + return m.matches(); + } + + public static String hintPhone(String phone){ + return phone.substring(0, 3) + "****" + phone.substring(7, 11); + } + +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/SelectPhotoUtils4.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/SelectPhotoUtils4.java new file mode 100644 index 0000000..a77622a --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/SelectPhotoUtils4.java @@ -0,0 +1,366 @@ +package com.dahe.mylibrary.utils; + +import android.app.Activity; +import android.graphics.Color; +import android.view.View; +import android.widget.ImageView; + +import androidx.core.content.ContextCompat; + +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.adapter.GridImageAdapter; +import com.dahe.mylibrary.dialog.DialogPhotoSelect; +import com.dahe.mylibrary.net.CommonResponseBean; +import com.dahe.mylibrary.weight.GlideEngine; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.luck.picture.lib.listener.OnResultCallbackListener; +import com.luck.picture.lib.style.PictureCropParameterStyle; +import com.luck.picture.lib.style.PictureParameterStyle; +import com.luck.picture.lib.style.PictureSelectorUIStyle; +import com.luck.picture.lib.tools.SdkVersionUtils; + +import java.lang.ref.WeakReference; +import java.util.List; + +public class SelectPhotoUtils4 implements View.OnClickListener { + + + + private Activity ctx; + private OnResultCallbackListener listener; + private GridImageAdapter mAdapter; + + public void selectSimple(Activity ctx,ImageView imageView, OnResultCallbackListener callbackListener){ + this.ctx = ctx; + this.listener = callbackListener; + imageView.setOnClickListener(this); + imageView.performClick(); + } + + + private final GridImageAdapter.onAddPicClickListener onAddPicClickListener = new GridImageAdapter.onAddPicClickListener() { + @Override + public void onAddPicClick() { + PictureSelector.create(ctx) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideEngine.createGlideEngine()) + .selectionMode(PictureConfig.MULTIPLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE + .maxSelectNum(6) + .isPreviewImage(true)// 是否可预览图片 true or fals + .isGif(false)// 是否显示gif图片 true or false + .isCamera(true)// 是否显示拍照按钮 true or false + .isEnableCrop(true)// 是否裁剪 true or false + .selectionData(mAdapter.getData())// 是否传入已选图片 + .circleDimmedLayer(false)// 是否圆形裁剪 true or false + .freeStyleCropEnabled(true)// 裁剪框是否可拖拽 true or false + + .minimumCompressSize(30)// 小于100kb的图片不压缩 + .showCropFrame(true)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false + .showCropGrid(true)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false +// .rotateEnabled(true) // 裁剪是否可旋转图片 true or false + .scaleEnabled(true)// 裁剪是否可放大缩小图片 true or false + .forResult(new MyResultCallback(mAdapter)); + } + + @Override + public void onDelPicClick(int postion, LocalMedia localMedia) { +// DataManager.getInstance().remove(localMedia.getId()+"") +// .compose(DataManager.setThread()) +// .subscribe(new BaseObserver(ctx, new RxHttpCallBack(ctx) { +// @Override +// public void onSuccess(CommonResponseBean t) { +// super.onSuccess(t); +//// list.remove(index); +// mAdapter.getData().remove(postion); +// mAdapter.notifyItemRemoved(postion); +// mAdapter.notifyItemRangeChanged(postion, mAdapter.getData().size()); +// } +// })); + } + }; + + /** + * 返回结果回调 + */ + private class MyResultCallback implements OnResultCallbackListener { + private WeakReference mAdapterWeakReference; + + public MyResultCallback(GridImageAdapter adapter) { + super(); + this.mAdapterWeakReference = new WeakReference<>(adapter); + } + + @Override + public void onResult(List result) { +// for (LocalMedia media : result) { +// Log.i(TAG, "是否压缩:" + media.isCompressed()); +// Log.i(TAG, "压缩:" + media.getCompressPath()); +// Log.i(TAG, "原图:" + media.getPath()); +// Log.i(TAG, "绝对路径:" + media.getRealPath()); +// Log.i(TAG, "是否裁剪:" + media.isCut()); +// Log.i(TAG, "裁剪:" + media.getCutPath()); +// Log.i(TAG, "是否开启原图:" + media.isOriginal()); +// Log.i(TAG, "原图路径:" + media.getOriginalPath()); +// Log.i(TAG, "Android Q 特有Path:" + media.getAndroidQToPath()); +// Log.i(TAG, "宽高: " + media.getWidth() + "x" + media.getHeight()); +// Log.i(TAG, "Size: " + media.getSize()); +// +// Log.i("MMM", "onResult: " + media.toString()); +// // TODO 可以通过PictureSelectorExternalUtils.getExifInterface();方法获取一些额外的资源信息,如旋转角度、经纬度等信息 +// } + listener.onResult(result); + if (mAdapterWeakReference.get() != null) { + mAdapterWeakReference.get().setList(result); + mAdapterWeakReference.get().notifyDataSetChanged(); + } + } + + @Override + public void onCancel() { +// Log.i(TAG, "PictureSelector Cancel"); + } + } + + + + + + + + + + + + + private PictureCropParameterStyle mCropParameterStyle; + + private PictureParameterStyle getDefaultStyle() { + // 相册主题 + PictureParameterStyle mPictureParameterStyle = new PictureParameterStyle(); + // 是否改变状态栏字体颜色(黑白切换) + mPictureParameterStyle.isChangeStatusBarFontColor = false; + // 是否开启右下角已完成(0/9)风格 + mPictureParameterStyle.isOpenCompletedNumStyle = false; + // 是否开启类似QQ相册带数字选择风格 + mPictureParameterStyle.isOpenCheckNumStyle = false; + // 相册状态栏背景色 + mPictureParameterStyle.pictureStatusBarColor = Color.parseColor("#393a3e"); + // 相册列表标题栏背景色 + mPictureParameterStyle.pictureTitleBarBackgroundColor = Color.parseColor("#393a3e"); + // 相册父容器背景色 + mPictureParameterStyle.pictureContainerBackgroundColor = ContextCompat.getColor(ctx, R.color.black); + // 相册列表标题栏右侧上拉箭头 + mPictureParameterStyle.pictureTitleUpResId = R.drawable.picture_icon_arrow_up; + // 相册列表标题栏右侧下拉箭头 + mPictureParameterStyle.pictureTitleDownResId = R.drawable.picture_icon_arrow_down; + // 相册文件夹列表选中圆点 + mPictureParameterStyle.pictureFolderCheckedDotStyle = R.drawable.picture_orange_oval; + // 相册返回箭头 + mPictureParameterStyle.pictureLeftBackIcon = R.drawable.picture_icon_back; + // 标题栏字体颜色 + mPictureParameterStyle.pictureTitleTextColor = ContextCompat.getColor(ctx, R.color.picture_color_white); + // 相册右侧取消按钮字体颜色 废弃 改用.pictureRightDefaultTextColor和.pictureRightDefaultTextColor + mPictureParameterStyle.pictureCancelTextColor = ContextCompat.getColor(ctx, R.color.picture_color_white); + // 选择相册目录背景样式 +// mPictureParameterStyle.pictureAlbumStyle = R.drawable.picture_new_item_select_bg; + // 相册列表勾选图片样式 + mPictureParameterStyle.pictureCheckedStyle = R.drawable.picture_checkbox_selector; + // 相册列表底部背景色 + mPictureParameterStyle.pictureBottomBgColor = ContextCompat.getColor(ctx, R.color.picture_color_grey); + // 已选数量圆点背景样式 + mPictureParameterStyle.pictureCheckNumBgStyle = R.drawable.picture_num_oval; + // 相册列表底下预览文字色值(预览按钮可点击时的色值) + mPictureParameterStyle.picturePreviewTextColor = ContextCompat.getColor(ctx, R.color.picture_color_fa632d); + // 相册列表底下不可预览文字色值(预览按钮不可点击时的色值) + mPictureParameterStyle.pictureUnPreviewTextColor = ContextCompat.getColor(ctx, R.color.picture_color_white); + // 相册列表已完成色值(已完成 可点击色值) + mPictureParameterStyle.pictureCompleteTextColor = ContextCompat.getColor(ctx, R.color.picture_color_fa632d); + // 相册列表未完成色值(请选择 不可点击色值) + mPictureParameterStyle.pictureUnCompleteTextColor = ContextCompat.getColor(ctx, R.color.picture_color_white); + // 预览界面底部背景色 + mPictureParameterStyle.picturePreviewBottomBgColor = ContextCompat.getColor(ctx, R.color.picture_color_grey); + // 外部预览界面删除按钮样式 + mPictureParameterStyle.pictureExternalPreviewDeleteStyle = R.drawable.picture_icon_delete; + // 原图按钮勾选样式 需设置.isOriginalImageControl(true); 才有效 + mPictureParameterStyle.pictureOriginalControlStyle = R.drawable.picture_original_wechat_checkbox; + // 原图文字颜色 需设置.isOriginalImageControl(true); 才有效 + mPictureParameterStyle.pictureOriginalFontColor = ContextCompat.getColor(ctx, R.color.white); + // 外部预览界面是否显示删除按钮 + mPictureParameterStyle.pictureExternalPreviewGonePreviewDelete = true; + // 设置NavBar Color SDK Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP有效 + mPictureParameterStyle.pictureNavBarColor = Color.parseColor("#393a3e"); + // 文件夹字体颜色 + mPictureParameterStyle.folderTextColor = Color.parseColor("#4d4d4d"); + // 文件夹字体大小 + mPictureParameterStyle.folderTextSize = 16; +// // 自定义相册右侧文本内容设置 +// mPictureParameterStyle.pictureRightDefaultText = ""; +// // 自定义相册未完成文本内容 +// mPictureParameterStyle.pictureUnCompleteText = ""; +// // 自定义相册完成文本内容 +// mPictureParameterStyle.pictureCompleteText = ""; +// // 自定义相册列表不可预览文字 +// mPictureParameterStyle.pictureUnPreviewText = ""; +// // 自定义相册列表预览文字 +// mPictureParameterStyle.picturePreviewText = ""; +// +// // 自定义相册标题字体大小 +// mPictureParameterStyle.pictureTitleTextSize = 18; +// // 自定义相册右侧文字大小 +// mPictureParameterStyle.pictureRightTextSize = 14; +// // 自定义相册预览文字大小 +// mPictureParameterStyle.picturePreviewTextSize = 14; +// // 自定义相册完成文字大小 +// mPictureParameterStyle.pictureCompleteTextSize = 14; +// // 自定义原图文字大小 +// mPictureParameterStyle.pictureOriginalTextSize = 14; + + // 裁剪主题 + mCropParameterStyle = new PictureCropParameterStyle( + ContextCompat.getColor(ctx, R.color.picture_color_grey), + ContextCompat.getColor(ctx, R.color.picture_color_grey), + Color.parseColor("#393a3e"), + ContextCompat.getColor(ctx, R.color.white), + mPictureParameterStyle.isChangeStatusBarFontColor); + + return mPictureParameterStyle; + } + + /** + * 相机拍照 + */ + private void doTakePhoto(Activity ctx) { + + // 裁剪主题 + mCropParameterStyle = new PictureCropParameterStyle( + ContextCompat.getColor(ctx, R.color.picture_color_grey), + ContextCompat.getColor(ctx, R.color.picture_color_grey), + Color.parseColor("#393a3e"), + ContextCompat.getColor(ctx, R.color.white), + false); + + PictureSelector.create(ctx) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideEngine.createGlideEngine()) + .setPictureCropStyle(mCropParameterStyle)// 动态自定义裁剪主题 + .minSelectNum(1) + .maxSelectNum(1) + .isSingleDirectReturn(true)// 单选模式下是否直接返回,PictureConfig.SINGLE模式下有效 +// .setPictureUIStyle(PictureSelectorUIStyle.ofDefaultStyle()) + .isEnableCrop(true)// 是否裁剪 true or false + .isCompress(true)// 是否压缩 true or false + .isGif(false)// 是否显示gif图片 true or false + .circleDimmedLayer(false)// 是否圆形裁剪 true or false + .freeStyleCropEnabled(true)// 裁剪框是否可拖拽 true or false + .cutOutQuality(30)// 裁剪压缩质量 默认90 int + .minimumCompressSize(30)// 小于100kb的图片不压缩 + .showCropFrame(true)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false + .showCropGrid(true)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false + .rotateEnabled(true) // 裁剪是否可旋转图片 true or false + .scaleEnabled(true)// 裁剪是否可放大缩小图片 true or false + .forResult(listener); + + + + // 单独拍照 +// PictureSelector.create(ctx) +// .openCamera(PictureMimeType.ofAll())// 单独拍照,也可录像或也可音频 看你传入的类型是图片or视频 +// .theme(R.style.picture_default_style)// 主题样式设置 具体参考 values/styles +// .imageEngine(GlideEngine.createGlideEngine())// 外部传入图片加载引擎,必传项 +// .maxSelectNum(1)// 最大图片选择数量 +// .minSelectNum(1)// 最小选择数量 +// .closeAndroidQChangeWH(true)//如果图片有旋转角度则对换宽高,默认为true +// .closeAndroidQChangeVideoWH(!SdkVersionUtils.checkedAndroid_Q())// 如果视频有旋转角度则对换宽高,默认false +// .selectionMode(cb_choose_mode.isChecked() ? +// PictureConfig.MULTIPLE : PictureConfig.SINGLE)// 多选 or 单选 +// .loadCacheResourcesCallback(GlideCacheEngine.createCacheEngine())// 获取图片资源缓存,主要是解决华为10部分机型在拷贝文件过多时会出现卡的问题,这里可以判断只在会出现一直转圈问题机型上使用 +// .isPreviewImage(cb_preview_img.isChecked())// 是否可预览图片 +// .isPreviewVideo(cb_preview_video.isChecked())// 是否可预览视频 +// .isEnablePreviewAudio(cb_preview_audio.isChecked()) // 是否可播放音频 +// .isCamera(cb_isCamera.isChecked())// 是否显示拍照按钮 +// .isEnableCrop(cb_crop.isChecked())// 是否裁剪 +// .isCompress(cb_compress.isChecked())// 是否压缩 +// .compressQuality(60)// 图片压缩后输出质量 +// .glideOverride(160, 160)// glide 加载宽高,越小图片列表越流畅,但会影响列表图片浏览的清晰度 +// .withAspectRatio(aspect_ratio_x, aspect_ratio_y)// 裁剪比例 如16:9 3:2 3:4 1:1 可自定义 +// .hideBottomControls(!cb_hide.isChecked())// 是否显示uCrop工具栏,默认不显示 +// .isGif(cb_isGif.isChecked())// 是否显示gif图片 +// .freeStyleCropEnabled(cb_styleCrop.isChecked())// 裁剪框是否可拖拽 +// .circleDimmedLayer(cb_crop_circular.isChecked())// 是否圆形裁剪 +// .showCropFrame(cb_showCropFrame.isChecked())// 是否显示裁剪矩形边框 圆形裁剪时建议设为false +// .showCropGrid(cb_showCropGrid.isChecked())// 是否显示裁剪矩形网格 圆形裁剪时建议设为false +// .isOpenClickSound(cb_voice.isChecked())// 是否开启点击声音 +// .selectionData(mAdapter.getData())// 是否传入已选图片 +// .cutOutQuality(90)// 裁剪输出质量 默认100 +// .minimumCompressSize(100)// 小于100kb的图片不压缩 +// .forResult(new MyResultCallback(mAdapter)); + } + + //从本地相册中选择 + private void doSelectPhoto(Activity ctx) { + PictureSelector.create(ctx) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideEngine.createGlideEngine()) + .selectionMode(PictureConfig.SINGLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE + .isPreviewImage(true)// 是否可预览图片 true or fals + .isGif(false)// 是否显示gif图片 true or false + .isCamera(false)// 是否显示拍照按钮 true or false + .isEnableCrop(true)// 是否裁剪 true or false + .isCompress(true)// 是否压缩 true or false + .circleDimmedLayer(false)// 是否圆形裁剪 true or false + .freeStyleCropEnabled(true)// 裁剪框是否可拖拽 true or false + .cutOutQuality(30)// 裁剪压缩质量 默认90 int + .minimumCompressSize(30)// 小于100kb的图片不压缩 + .showCropFrame(true)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false + .showCropGrid(true)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false + .rotateEnabled(true) // 裁剪是否可旋转图片 true or false + .scaleEnabled(true)// 裁剪是否可放大缩小图片 true or false + .forResult(listener); +// .forResult(PictureConfig.CHOOSE_REQUEST); + } + + + @Override + public void onClick(View view) { + +// PictureSelector.create(ctx) +// .openGallery(PictureMimeType.ofImage()) +// .imageEngine(GlideEngine.createGlideEngine()) +// .selectionMode(PictureConfig.SINGLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE +// .isSingleDirectReturn(true) +// .maxSelectNum(1) +// .minSelectNum(1) +// .isPreviewImage(true)// 是否可预览图片 true or fals +// .isGif(false)// 是否显示gif图片 true or false +// .isCamera(true)// 是否显示拍照按钮 true or false +// .isEnableCrop(true)// 是否裁剪 true or false +// .isCompress(true)// 是否压缩 true or false +// .circleDimmedLayer(false)// 是否圆形裁剪 true or false +// .freeStyleCropEnabled(true)// 裁剪框是否可拖拽 true or false +// .cutOutQuality(30)// 裁剪压缩质量 默认90 int +// .minimumCompressSize(100)// 小于100kb的图片不压缩 +// .showCropFrame(true)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false +// .showCropGrid(true)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false +// .rotateEnabled(true) // 裁剪是否可旋转图片 true or false +// .scaleEnabled(true)// 裁剪是否可放大缩小图片 true or false +// .forResult(listener); + + + DialogPhotoSelect dialogPhotoSelect = new DialogPhotoSelect(ctx); + dialogPhotoSelect.show(); + dialogPhotoSelect.setOnSelectClickListener(new DialogPhotoSelect.onSelectClickListener() { + @Override + public void onTakePhoto() { + doTakePhoto(ctx); + } + + @Override + public void onSelectPhoto() { + doSelectPhoto(ctx); + } + }); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/SelectPhotoUtils5.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/SelectPhotoUtils5.java new file mode 100644 index 0000000..4eeb7a9 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/SelectPhotoUtils5.java @@ -0,0 +1,353 @@ +package com.dahe.mylibrary.utils; + +import android.app.Activity; +import android.graphics.Color; +import android.view.View; +import android.widget.ImageView; + +import androidx.core.content.ContextCompat; + +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.adapter.GridImageAdapter; +import com.dahe.mylibrary.dialog.DialogPhotoSelect; +import com.dahe.mylibrary.weight.GlideEngine; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.luck.picture.lib.listener.OnResultCallbackListener; +import com.luck.picture.lib.style.PictureCropParameterStyle; +import com.luck.picture.lib.style.PictureParameterStyle; + +import java.lang.ref.WeakReference; +import java.util.List; + +public class SelectPhotoUtils5 implements View.OnClickListener { + + private SelectPhotoUtils5 selectPhotoUtils5; + private Activity ctx; + private OnResultCallbackListener listener; + private GridImageAdapter mAdapter; + + public void selectSimple(Activity ctx, ImageView imageView, OnResultCallbackListener callbackListener) { + this.ctx = ctx; + this.listener = callbackListener; + imageView.setOnClickListener(this); + imageView.performClick(); + } + + + + + private final GridImageAdapter.onAddPicClickListener onAddPicClickListener = new GridImageAdapter.onAddPicClickListener() { + @Override + public void onAddPicClick() { + PictureSelector.create(ctx) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideEngine.createGlideEngine()) + .selectionMode(PictureConfig.MULTIPLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE + .maxSelectNum(6) + .isPreviewImage(true)// 是否可预览图片 true or fals + .isGif(false)// 是否显示gif图片 true or false + .isCamera(true)// 是否显示拍照按钮 true or false + .isEnableCrop(false)// 是否裁剪 true or false + .selectionData(mAdapter.getData())// 是否传入已选图片 + .circleDimmedLayer(false)// 是否圆形裁剪 true or false + .freeStyleCropEnabled(true)// 裁剪框是否可拖拽 true or false + + .minimumCompressSize(30)// 小于100kb的图片不压缩 + .showCropFrame(true)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false + .showCropGrid(true)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false +// .rotateEnabled(true) // 裁剪是否可旋转图片 true or false + .scaleEnabled(true)// 裁剪是否可放大缩小图片 true or false + .forResult(new MyResultCallback(mAdapter)); + } + + @Override + public void onDelPicClick(int postion, LocalMedia localMedia) { +// DataManager.getInstance().remove(localMedia.getId()+"") +// .compose(DataManager.setThread()) +// .subscribe(new BaseObserver(ctx, new RxHttpCallBack(ctx) { +// @Override +// public void onSuccess(CommonResponseBean t) { +// super.onSuccess(t); +//// list.remove(index); +// mAdapter.getData().remove(postion); +// mAdapter.notifyItemRemoved(postion); +// mAdapter.notifyItemRangeChanged(postion, mAdapter.getData().size()); +// } +// })); + } + }; + + /** + * 返回结果回调 + */ + private class MyResultCallback implements OnResultCallbackListener { + private WeakReference mAdapterWeakReference; + + public MyResultCallback(GridImageAdapter adapter) { + super(); + this.mAdapterWeakReference = new WeakReference<>(adapter); + } + + @Override + public void onResult(List result) { +// for (LocalMedia media : result) { +// Log.i(TAG, "是否压缩:" + media.isCompressed()); +// Log.i(TAG, "压缩:" + media.getCompressPath()); +// Log.i(TAG, "原图:" + media.getPath()); +// Log.i(TAG, "绝对路径:" + media.getRealPath()); +// Log.i(TAG, "是否裁剪:" + media.isCut()); +// Log.i(TAG, "裁剪:" + media.getCutPath()); +// Log.i(TAG, "是否开启原图:" + media.isOriginal()); +// Log.i(TAG, "原图路径:" + media.getOriginalPath()); +// Log.i(TAG, "Android Q 特有Path:" + media.getAndroidQToPath()); +// Log.i(TAG, "宽高: " + media.getWidth() + "x" + media.getHeight()); +// Log.i(TAG, "Size: " + media.getSize()); +// +// Log.i("MMM", "onResult: " + media.toString()); +// // TODO 可以通过PictureSelectorExternalUtils.getExifInterface();方法获取一些额外的资源信息,如旋转角度、经纬度等信息 +// } + listener.onResult(result); + if (mAdapterWeakReference.get() != null) { + mAdapterWeakReference.get().setList(result); + mAdapterWeakReference.get().notifyDataSetChanged(); + } + } + + @Override + public void onCancel() { +// Log.i(TAG, "PictureSelector Cancel"); + } + } + + + private PictureCropParameterStyle mCropParameterStyle; + + private PictureParameterStyle getDefaultStyle() { + // 相册主题 + PictureParameterStyle mPictureParameterStyle = new PictureParameterStyle(); + // 是否改变状态栏字体颜色(黑白切换) + mPictureParameterStyle.isChangeStatusBarFontColor = false; + // 是否开启右下角已完成(0/9)风格 + mPictureParameterStyle.isOpenCompletedNumStyle = false; + // 是否开启类似QQ相册带数字选择风格 + mPictureParameterStyle.isOpenCheckNumStyle = false; + // 相册状态栏背景色 + mPictureParameterStyle.pictureStatusBarColor = Color.parseColor("#393a3e"); + // 相册列表标题栏背景色 + mPictureParameterStyle.pictureTitleBarBackgroundColor = Color.parseColor("#393a3e"); + // 相册父容器背景色 + mPictureParameterStyle.pictureContainerBackgroundColor = ContextCompat.getColor(ctx, R.color.black); + // 相册列表标题栏右侧上拉箭头 + mPictureParameterStyle.pictureTitleUpResId = R.drawable.picture_icon_arrow_up; + // 相册列表标题栏右侧下拉箭头 + mPictureParameterStyle.pictureTitleDownResId = R.drawable.picture_icon_arrow_down; + // 相册文件夹列表选中圆点 + mPictureParameterStyle.pictureFolderCheckedDotStyle = R.drawable.picture_orange_oval; + // 相册返回箭头 + mPictureParameterStyle.pictureLeftBackIcon = R.drawable.picture_icon_back; + // 标题栏字体颜色 + mPictureParameterStyle.pictureTitleTextColor = ContextCompat.getColor(ctx, R.color.picture_color_white); + // 相册右侧取消按钮字体颜色 废弃 改用.pictureRightDefaultTextColor和.pictureRightDefaultTextColor + mPictureParameterStyle.pictureCancelTextColor = ContextCompat.getColor(ctx, R.color.picture_color_white); + // 选择相册目录背景样式 +// mPictureParameterStyle.pictureAlbumStyle = R.drawable.picture_new_item_select_bg; + // 相册列表勾选图片样式 + mPictureParameterStyle.pictureCheckedStyle = R.drawable.picture_checkbox_selector; + // 相册列表底部背景色 + mPictureParameterStyle.pictureBottomBgColor = ContextCompat.getColor(ctx, R.color.picture_color_grey); + // 已选数量圆点背景样式 + mPictureParameterStyle.pictureCheckNumBgStyle = R.drawable.picture_num_oval; + // 相册列表底下预览文字色值(预览按钮可点击时的色值) + mPictureParameterStyle.picturePreviewTextColor = ContextCompat.getColor(ctx, R.color.picture_color_fa632d); + // 相册列表底下不可预览文字色值(预览按钮不可点击时的色值) + mPictureParameterStyle.pictureUnPreviewTextColor = ContextCompat.getColor(ctx, R.color.picture_color_white); + // 相册列表已完成色值(已完成 可点击色值) + mPictureParameterStyle.pictureCompleteTextColor = ContextCompat.getColor(ctx, R.color.picture_color_fa632d); + // 相册列表未完成色值(请选择 不可点击色值) + mPictureParameterStyle.pictureUnCompleteTextColor = ContextCompat.getColor(ctx, R.color.picture_color_white); + // 预览界面底部背景色 + mPictureParameterStyle.picturePreviewBottomBgColor = ContextCompat.getColor(ctx, R.color.picture_color_grey); + // 外部预览界面删除按钮样式 + mPictureParameterStyle.pictureExternalPreviewDeleteStyle = R.drawable.picture_icon_delete; + // 原图按钮勾选样式 需设置.isOriginalImageControl(true); 才有效 + mPictureParameterStyle.pictureOriginalControlStyle = R.drawable.picture_original_wechat_checkbox; + // 原图文字颜色 需设置.isOriginalImageControl(true); 才有效 + mPictureParameterStyle.pictureOriginalFontColor = ContextCompat.getColor(ctx, R.color.white); + // 外部预览界面是否显示删除按钮 + mPictureParameterStyle.pictureExternalPreviewGonePreviewDelete = true; + // 设置NavBar Color SDK Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP有效 + mPictureParameterStyle.pictureNavBarColor = Color.parseColor("#393a3e"); + // 文件夹字体颜色 + mPictureParameterStyle.folderTextColor = Color.parseColor("#4d4d4d"); + // 文件夹字体大小 + mPictureParameterStyle.folderTextSize = 16; +// // 自定义相册右侧文本内容设置 +// mPictureParameterStyle.pictureRightDefaultText = ""; +// // 自定义相册未完成文本内容 +// mPictureParameterStyle.pictureUnCompleteText = ""; +// // 自定义相册完成文本内容 +// mPictureParameterStyle.pictureCompleteText = ""; +// // 自定义相册列表不可预览文字 +// mPictureParameterStyle.pictureUnPreviewText = ""; +// // 自定义相册列表预览文字 +// mPictureParameterStyle.picturePreviewText = ""; +// +// // 自定义相册标题字体大小 +// mPictureParameterStyle.pictureTitleTextSize = 18; +// // 自定义相册右侧文字大小 +// mPictureParameterStyle.pictureRightTextSize = 14; +// // 自定义相册预览文字大小 +// mPictureParameterStyle.picturePreviewTextSize = 14; +// // 自定义相册完成文字大小 +// mPictureParameterStyle.pictureCompleteTextSize = 14; +// // 自定义原图文字大小 +// mPictureParameterStyle.pictureOriginalTextSize = 14; + + // 裁剪主题 + mCropParameterStyle = new PictureCropParameterStyle( + ContextCompat.getColor(ctx, R.color.picture_color_grey), + ContextCompat.getColor(ctx, R.color.picture_color_grey), + Color.parseColor("#393a3e"), + ContextCompat.getColor(ctx, R.color.white), + mPictureParameterStyle.isChangeStatusBarFontColor); + + return mPictureParameterStyle; + } + + /** + * 相机拍照 + */ + private void doTakePhoto(Activity ctx) { + + // 裁剪主题 + mCropParameterStyle = new PictureCropParameterStyle( + ContextCompat.getColor(ctx, R.color.picture_color_grey), + ContextCompat.getColor(ctx, R.color.picture_color_grey), + Color.parseColor("#393a3e"), + ContextCompat.getColor(ctx, R.color.white), + false); + + PictureSelector.create(ctx) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideEngine.createGlideEngine()) + .setPictureCropStyle(mCropParameterStyle)// 动态自定义裁剪主题 + .minSelectNum(1) + .maxSelectNum(1) + .isSingleDirectReturn(true)// 单选模式下是否直接返回,PictureConfig.SINGLE模式下有效 +// .setPictureUIStyle(PictureSelectorUIStyle.ofDefaultStyle()) + .isEnableCrop(false)// 是否裁剪 true or false + .isCompress(true)// 是否压缩 true or false + .isGif(false)// 是否显示gif图片 true or false + .circleDimmedLayer(false)// 是否圆形裁剪 true or false + .freeStyleCropEnabled(true)// 裁剪框是否可拖拽 true or false + .cutOutQuality(30)// 裁剪压缩质量 默认90 int + .minimumCompressSize(30)// 小于100kb的图片不压缩 + .showCropFrame(true)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false + .showCropGrid(true)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false + .rotateEnabled(true) // 裁剪是否可旋转图片 true or false + .scaleEnabled(true)// 裁剪是否可放大缩小图片 true or false + .forResult(listener); + + + // 单独拍照 +// PictureSelector.create(ctx) +// .openCamera(PictureMimeType.ofAll())// 单独拍照,也可录像或也可音频 看你传入的类型是图片or视频 +// .theme(R.style.picture_default_style)// 主题样式设置 具体参考 values/styles +// .imageEngine(GlideEngine.createGlideEngine())// 外部传入图片加载引擎,必传项 +// .maxSelectNum(1)// 最大图片选择数量 +// .minSelectNum(1)// 最小选择数量 +// .closeAndroidQChangeWH(true)//如果图片有旋转角度则对换宽高,默认为true +// .closeAndroidQChangeVideoWH(!SdkVersionUtils.checkedAndroid_Q())// 如果视频有旋转角度则对换宽高,默认false +// .selectionMode(cb_choose_mode.isChecked() ? +// PictureConfig.MULTIPLE : PictureConfig.SINGLE)// 多选 or 单选 +// .loadCacheResourcesCallback(GlideCacheEngine.createCacheEngine())// 获取图片资源缓存,主要是解决华为10部分机型在拷贝文件过多时会出现卡的问题,这里可以判断只在会出现一直转圈问题机型上使用 +// .isPreviewImage(cb_preview_img.isChecked())// 是否可预览图片 +// .isPreviewVideo(cb_preview_video.isChecked())// 是否可预览视频 +// .isEnablePreviewAudio(cb_preview_audio.isChecked()) // 是否可播放音频 +// .isCamera(cb_isCamera.isChecked())// 是否显示拍照按钮 +// .isEnableCrop(cb_crop.isChecked())// 是否裁剪 +// .isCompress(cb_compress.isChecked())// 是否压缩 +// .compressQuality(60)// 图片压缩后输出质量 +// .glideOverride(160, 160)// glide 加载宽高,越小图片列表越流畅,但会影响列表图片浏览的清晰度 +// .withAspectRatio(aspect_ratio_x, aspect_ratio_y)// 裁剪比例 如16:9 3:2 3:4 1:1 可自定义 +// .hideBottomControls(!cb_hide.isChecked())// 是否显示uCrop工具栏,默认不显示 +// .isGif(cb_isGif.isChecked())// 是否显示gif图片 +// .freeStyleCropEnabled(cb_styleCrop.isChecked())// 裁剪框是否可拖拽 +// .circleDimmedLayer(cb_crop_circular.isChecked())// 是否圆形裁剪 +// .showCropFrame(cb_showCropFrame.isChecked())// 是否显示裁剪矩形边框 圆形裁剪时建议设为false +// .showCropGrid(cb_showCropGrid.isChecked())// 是否显示裁剪矩形网格 圆形裁剪时建议设为false +// .isOpenClickSound(cb_voice.isChecked())// 是否开启点击声音 +// .selectionData(mAdapter.getData())// 是否传入已选图片 +// .cutOutQuality(90)// 裁剪输出质量 默认100 +// .minimumCompressSize(100)// 小于100kb的图片不压缩 +// .forResult(new MyResultCallback(mAdapter)); + } + + //从本地相册中选择 + private void doSelectPhoto(Activity ctx) { + PictureSelector.create(ctx) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideEngine.createGlideEngine()) + .selectionMode(PictureConfig.SINGLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE + .isPreviewImage(true)// 是否可预览图片 true or fals + .isGif(false)// 是否显示gif图片 true or false + .isCamera(false)// 是否显示拍照按钮 true or false + .isEnableCrop(false)// 是否裁剪 true or false + .isCompress(true)// 是否压缩 true or false + .circleDimmedLayer(false)// 是否圆形裁剪 true or false + .freeStyleCropEnabled(true)// 裁剪框是否可拖拽 true or false + .cutOutQuality(30)// 裁剪压缩质量 默认90 int + .minimumCompressSize(30)// 小于100kb的图片不压缩 + .showCropFrame(true)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false + .showCropGrid(true)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false + .rotateEnabled(true) // 裁剪是否可旋转图片 true or false + .scaleEnabled(true)// 裁剪是否可放大缩小图片 true or false + .forResult(listener); +// .forResult(PictureConfig.CHOOSE_REQUEST); + } + + + @Override + public void onClick(View view) { + +// PictureSelector.create(ctx) +// .openGallery(PictureMimeType.ofImage()) +// .imageEngine(GlideEngine.createGlideEngine()) +// .selectionMode(PictureConfig.SINGLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE +// .isSingleDirectReturn(true) +// .maxSelectNum(1) +// .minSelectNum(1) +// .isPreviewImage(true)// 是否可预览图片 true or fals +// .isGif(false)// 是否显示gif图片 true or false +// .isCamera(true)// 是否显示拍照按钮 true or false +// .isEnableCrop(true)// 是否裁剪 true or false +// .isCompress(true)// 是否压缩 true or false +// .circleDimmedLayer(false)// 是否圆形裁剪 true or false +// .freeStyleCropEnabled(true)// 裁剪框是否可拖拽 true or false +// .cutOutQuality(30)// 裁剪压缩质量 默认90 int +// .minimumCompressSize(100)// 小于100kb的图片不压缩 +// .showCropFrame(true)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false +// .showCropGrid(true)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false +// .rotateEnabled(true) // 裁剪是否可旋转图片 true or false +// .scaleEnabled(true)// 裁剪是否可放大缩小图片 true or false +// .forResult(listener); + + + DialogPhotoSelect dialogPhotoSelect = new DialogPhotoSelect(ctx); + dialogPhotoSelect.show(); + dialogPhotoSelect.setOnSelectClickListener(new DialogPhotoSelect.onSelectClickListener() { + @Override + public void onTakePhoto() { + doTakePhoto(ctx); + } + + @Override + public void onSelectPhoto() { + doSelectPhoto(ctx); + } + }); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/SelectPhotoUtils6.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/SelectPhotoUtils6.java new file mode 100644 index 0000000..02b244c --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/SelectPhotoUtils6.java @@ -0,0 +1,318 @@ +package com.dahe.mylibrary.utils; + +import android.app.Activity; +import android.content.pm.ActivityInfo; +import android.text.TextUtils; +import android.view.View; +import android.widget.ImageView; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.adapter.GridImageAdapter; +import com.dahe.mylibrary.dialog.DialogPhotoSelect; +import com.dahe.mylibrary.net.CommonResponseBean; +import com.dahe.mylibrary.weight.FullyGridLayoutManager; +import com.dahe.mylibrary.weight.GlideEngine; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.decoration.GridSpacingItemDecoration; +import com.luck.picture.lib.entity.LocalMedia; +import com.luck.picture.lib.listener.OnResultCallbackListener; +import com.luck.picture.lib.tools.ScreenUtils; + +import java.lang.ref.WeakReference; +import java.util.List; + +public class SelectPhotoUtils6 implements View.OnClickListener { + private Activity ctx; + private OnResultCallbackListener listener; + private GridImageAdapter mAdapter; + private Build build; + + private SelectPhotoUtils6(Build build, Activity ctx) { + this.build = build; + this.ctx = ctx; + this.listener = build.listener; + if (null == listener) { + ToastUtils.showToast(ctx, "请初始化回调listener"); + return; + } + if (build.isSingle) {//单选 + if (null == build.imageView) { + ToastUtils.showToast(ctx, "请初始化ImageView"); + return; + } + selectSimple(build.imageView); + } else {//多选 + if (null == build.recyclerView || !(build.recyclerView instanceof RecyclerView)) { + ToastUtils.showToast(ctx, "请初始化RecycleView"); + return; + } + selectMul(build.recyclerView); + + } + } + + + public static class Build { + private int maxSelect; + private boolean isSingle; + private boolean isOnlyShow; + private ImageView imageView; + private RecyclerView recyclerView; + private List pics; + private OnResultCallbackListener listener; + + public Build maxSelect(int max) { + this.maxSelect = max; + return this; + } + + public Build isSingle(boolean isSingle) { + this.isSingle = isSingle; + return this; + } + + public Build isOnlyShow(boolean isOnlyShow) { + this.isOnlyShow = isOnlyShow; + return this; + } + + public Build imageview(ImageView imageView) { + this.imageView = imageView; + return this; + } + + public Build recycleview(RecyclerView recyclerView) { + this.recyclerView = recyclerView; + return this; + } + + public Build newPics(List pics) { + this.pics = pics; + return this; + } + + public Build resultListener(OnResultCallbackListener listener) { + this.listener = listener; + return this; + } + + public SelectPhotoUtils6 create(Activity ctx) { + return new SelectPhotoUtils6(this, ctx); + } + } + + public GridImageAdapter getmAdapter() { + return mAdapter; + } + + + public void selectSimple(ImageView imageView) { + imageView.setOnClickListener(this); + } + + + public void selectMul(RecyclerView recyclerView) { + FullyGridLayoutManager manager = new FullyGridLayoutManager(ctx, + 4, GridLayoutManager.VERTICAL, false); + + recyclerView.addItemDecoration(new GridSpacingItemDecoration(40, + ScreenUtils.dip2px(ctx, 8), true + )); + recyclerView.setLayoutManager(manager); + mAdapter = new GridImageAdapter(ctx, onAddPicClickListener); + mAdapter.setSelectMax(build.maxSelect); + mAdapter.setIsOnlyShow(build.isOnlyShow); + recyclerView.setAdapter(mAdapter); + + mAdapter.setOnItemClickListener((v, position) -> { + List selectList = mAdapter.getData(); + if (selectList.size() > 0) { + LocalMedia media = selectList.get(position); + String mimeType = media.getMimeType(); + int mediaType = PictureMimeType.getMimeType(mimeType); + switch (mediaType) { + case PictureConfig.TYPE_VIDEO: + // 预览视频 + PictureSelector.create(ctx) + .themeStyle(R.style.picture_default_style) +// .setPictureStyle(mPictureParameterStyle)// 动态自定义相册主题 + .externalPictureVideo(TextUtils.isEmpty(media.getAndroidQToPath()) ? media.getPath() : media.getAndroidQToPath()); + break; + case PictureConfig.TYPE_AUDIO: + // 预览音频 + PictureSelector.create(ctx) + .externalPictureAudio(PictureMimeType.isContent(media.getPath()) ? media.getAndroidQToPath() : media.getPath()); + break; + default: + // 预览图片 可自定长按保存路径 +// PictureWindowAnimationStyle animationStyle = new PictureWindowAnimationStyle(); +// animationStyle.activityPreviewEnterAnimation = R.anim.picture_anim_up_in; +// animationStyle.activityPreviewExitAnimation = R.anim.picture_anim_down_out; + PictureSelector.create(ctx) + .themeStyle(R.style.picture_default_style) // xml设置主题 +// .setPictureStyle(mPictureParameterStyle)// 动态自定义相册主题 + //.setPictureWindowAnimationStyle(animationStyle)// 自定义页面启动动画 + .setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)// 设置相册Activity方向,不设置默认使用系统 + .isNotPreviewDownload(true)// 预览图片长按是否可以下载 + //.bindCustomPlayVideoCallback(new MyVideoSelectedPlayCallback(getContext()))// 自定义播放回调控制,用户可以使用自己的视频播放界面 + .imageEngine(GlideEngine.createGlideEngine())// 外部传入图片加载引擎,必传项 + .openExternalPreview(position, selectList); + break; + } + } + }); + } + + + private final GridImageAdapter.onAddPicClickListener onAddPicClickListener = new GridImageAdapter.onAddPicClickListener() { + @Override + public void onAddPicClick() { + PictureSelector.create(ctx) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideEngine.createGlideEngine()) + .selectionMode(build.isSingle ? PictureConfig.SINGLE : PictureConfig.MULTIPLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE + .maxSelectNum(build.maxSelect) + .isPreviewImage(true)// 是否可预览图片 true or fals + .isGif(false)// 是否显示gif图片 true or false + .isCamera(true)// 是否显示拍照按钮 true or false + .isEnableCrop(false)// 是否裁剪 true or false + .selectionData(mAdapter.getData())// 是否传入已选图片 + .isCompress(true)// 是否压缩 true or false + .circleDimmedLayer(false)// 是否圆形裁剪 true or false + .freeStyleCropEnabled(false)// 裁剪框是否可拖拽 true or false + .cutOutQuality(30)// 裁剪压缩质量 默认90 int + .minimumCompressSize(30)// 小于100kb的图片不压缩 + .showCropFrame(false)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false + .showCropGrid(false)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false +// .rotateEnabled(true) // 裁剪是否可旋转图片 true or false + .scaleEnabled(false)// 裁剪是否可放大缩小图片 true or false + .forResult(new MyResultCallback(mAdapter)); + } + + @Override + public void onDelPicClick(int postion, LocalMedia localMedia) { +// DataManager.getInstance().remove(localMedia.getId() + "") +// .compose(DataManager.setThread()) +// .subscribe(new BaseObserver(ctx, new RxHttpCallBack(ctx) { +// @Override +// public void onSuccess(CommonResponseBean t) { +// super.onSuccess(t); +//// list.remove(index); +// mAdapter.getData().remove(postion); +// mAdapter.notifyItemRemoved(postion); +// mAdapter.notifyItemRangeChanged(postion, mAdapter.getData().size()); +// } +// })); + } + }; + + /** + * 返回结果回调 + */ + private class MyResultCallback implements OnResultCallbackListener { + private WeakReference mAdapterWeakReference; + + public MyResultCallback(GridImageAdapter adapter) { + super(); + this.mAdapterWeakReference = new WeakReference<>(adapter); + } + + @Override + public void onResult(List result) { +// for (LocalMedia media : result) { +// Log.i(TAG, "是否压缩:" + media.isCompressed()); +// Log.i(TAG, "压缩:" + media.getCompressPath()); +// Log.i(TAG, "原图:" + media.getPath()); +// Log.i(TAG, "绝对路径:" + media.getRealPath()); +// Log.i(TAG, "是否裁剪:" + media.isCut()); +// Log.i(TAG, "裁剪:" + media.getCutPath()); +// Log.i(TAG, "是否开启原图:" + media.isOriginal()); +// Log.i(TAG, "原图路径:" + media.getOriginalPath()); +// Log.i(TAG, "Android Q 特有Path:" + media.getAndroidQToPath()); +// Log.i(TAG, "宽高: " + media.getWidth() + "x" + media.getHeight()); +// Log.i(TAG, "Size: " + media.getSize()); +// +// Log.i("MMM", "onResult: " + media.toString()); +// // TODO 可以通过PictureSelectorExternalUtils.getExifInterface();方法获取一些额外的资源信息,如旋转角度、经纬度等信息 +// } + listener.onResult(result); + if (mAdapterWeakReference.get() != null) { + mAdapterWeakReference.get().setList(result); + mAdapterWeakReference.get().notifyDataSetChanged(); + } + } + + @Override + public void onCancel() { +// Log.i(TAG, "PictureSelector Cancel"); + } + } + + + /** + * 相机拍照 + */ + private void doTakePhoto(Activity ctx) { + PictureSelector.create(ctx) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideEngine.createGlideEngine()) + .isEnableCrop(false)// 是否裁剪 true or false + .isCompress(true)// 是否压缩 true or false + .isGif(false)// 是否显示gif图片 true or false + .circleDimmedLayer(false)// 是否圆形裁剪 true or false + .freeStyleCropEnabled(false)// 裁剪框是否可拖拽 true or false + .cutOutQuality(30)// 裁剪压缩质量 默认90 int + .minimumCompressSize(30)// 小于100kb的图片不压缩 + .showCropFrame(false)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false + .showCropGrid(false)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false + .rotateEnabled(false) // 裁剪是否可旋转图片 true or false + .scaleEnabled(false)// 裁剪是否可放大缩小图片 true or false + .forResult(listener); + } + + //从本地相册中选择 + private void doSelectPhoto(Activity ctx) { + PictureSelector.create(ctx) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideEngine.createGlideEngine()) + .selectionMode(PictureConfig.SINGLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE + .isPreviewImage(true)// 是否可预览图片 true or fals + .isGif(false)// 是否显示gif图片 true or false + .isCamera(false)// 是否显示拍照按钮 true or false + .isEnableCrop(false)// 是否裁剪 true or false + .isCompress(true)// 是否压缩 true or false + .circleDimmedLayer(false)// 是否圆形裁剪 true or false + .freeStyleCropEnabled(false)// 裁剪框是否可拖拽 true or false + .cutOutQuality(30)// 裁剪压缩质量 默认90 int + .minimumCompressSize(30)// 小于100kb的图片不压缩 + .showCropFrame(false)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false + .showCropGrid(false)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false +// .rotateEnabled(true) // 裁剪是否可旋转图片 true or false + .scaleEnabled(false)// 裁剪是否可放大缩小图片 true or false + .forResult(listener); +// .forResult(PictureConfig.CHOOSE_REQUEST); + } + + + @Override + public void onClick(View view) { + DialogPhotoSelect dialogPhotoSelect = new DialogPhotoSelect(ctx); + dialogPhotoSelect.show(); + dialogPhotoSelect.setOnSelectClickListener(new DialogPhotoSelect.onSelectClickListener() { + @Override + public void onTakePhoto() { + doTakePhoto(ctx); + } + + @Override + public void onSelectPhoto() { + doSelectPhoto(ctx); + } + }); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/ShellUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/ShellUtils.java new file mode 100644 index 0000000..caf3f45 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/ShellUtils.java @@ -0,0 +1,201 @@ +package com.dahe.mylibrary.utils; + + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.List; + +/** + *
+ *     author: Blankj
+ *     blog  : http://blankj.com
+ *     time  : 2016/08/07
+ *     desc  : utils about shell
+ * 
+ */ +public final class ShellUtils { + + private static final String LINE_SEP = System.getProperty("line.separator"); + + private ShellUtils() { + throw new UnsupportedOperationException("u can't instantiate me..."); + } + + /** + * Execute the command. + * + * @param command The command. + * @param isRooted True to use root, false otherwise. + * @return the single {@link CommandResult} instance + */ + public static CommandResult execCmd(final String command, final boolean isRooted) { + return execCmd(new String[]{command}, isRooted, true); + } + + /** + * Execute the command. + * + * @param commands The commands. + * @param isRooted True to use root, false otherwise. + * @return the single {@link CommandResult} instance + */ + public static CommandResult execCmd(final List commands, final boolean isRooted) { + return execCmd(commands == null ? null : commands.toArray(new String[]{}), isRooted, true); + } + + /** + * Execute the command. + * + * @param commands The commands. + * @param isRooted True to use root, false otherwise. + * @return the single {@link CommandResult} instance + */ + public static CommandResult execCmd(final String[] commands, final boolean isRooted) { + return execCmd(commands, isRooted, true); + } + + /** + * Execute the command. + * + * @param command The command. + * @param isRooted True to use root, false otherwise. + * @param isNeedResultMsg True to node_return the message of result, false otherwise. + * @return the single {@link CommandResult} instance + */ + public static CommandResult execCmd(final String command, + final boolean isRooted, + final boolean isNeedResultMsg) { + return execCmd(new String[]{command}, isRooted, isNeedResultMsg); + } + + /** + * Execute the command. + * + * @param commands The commands. + * @param isRooted True to use root, false otherwise. + * @param isNeedResultMsg True to node_return the message of result, false otherwise. + * @return the single {@link CommandResult} instance + */ + public static CommandResult execCmd(final List commands, + final boolean isRooted, + final boolean isNeedResultMsg) { + return execCmd(commands == null ? null : commands.toArray(new String[]{}), + isRooted, + isNeedResultMsg); + } + + /** + * Execute the command. + * + * @param commands The commands. + * @param isRooted True to use root, false otherwise. + * @param isNeedResultMsg True to node_return the message of result, false otherwise. + * @return the single {@link CommandResult} instance + */ + public static CommandResult execCmd(final String[] commands, + final boolean isRooted, + final boolean isNeedResultMsg) { + int result = -1; + if (commands == null || commands.length == 0) { + return new CommandResult(result, "", ""); + } + Process process = null; + BufferedReader successResult = null; + BufferedReader errorResult = null; + StringBuilder successMsg = null; + StringBuilder errorMsg = null; + DataOutputStream os = null; + try { + process = Runtime.getRuntime().exec(isRooted ? "su" : "sh"); + os = new DataOutputStream(process.getOutputStream()); + for (String command : commands) { + if (command == null) continue; + os.write(command.getBytes()); + os.writeBytes(LINE_SEP); + os.flush(); + } + os.writeBytes("exit" + LINE_SEP); + os.flush(); + result = process.waitFor(); + if (isNeedResultMsg) { + successMsg = new StringBuilder(); + errorMsg = new StringBuilder(); + successResult = new BufferedReader( + new InputStreamReader(process.getInputStream(), "UTF-8") + ); + errorResult = new BufferedReader( + new InputStreamReader(process.getErrorStream(), "UTF-8") + ); + String line; + if ((line = successResult.readLine()) != null) { + successMsg.append(line); + while ((line = successResult.readLine()) != null) { + successMsg.append(LINE_SEP).append(line); + } + } + if ((line = errorResult.readLine()) != null) { + errorMsg.append(line); + while ((line = errorResult.readLine()) != null) { + errorMsg.append(LINE_SEP).append(line); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (os != null) { + os.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + try { + if (successResult != null) { + successResult.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + try { + if (errorResult != null) { + errorResult.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + if (process != null) { + process.destroy(); + } + } + return new CommandResult( + result, + successMsg == null ? "" : successMsg.toString(), + errorMsg == null ? "" : errorMsg.toString() + ); + } + + /** + * The result of command. + */ + public static class CommandResult { + public int result; + public String successMsg; + public String errorMsg; + + public CommandResult(final int result, final String successMsg, final String errorMsg) { + this.result = result; + this.successMsg = successMsg; + this.errorMsg = errorMsg; + } + + @Override + public String toString() { + return "result: " + result + "\n" + + "successMsg: " + successMsg + "\n" + + "errorMsg: " + errorMsg; + } + } +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/SmsTimeUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/SmsTimeUtils.java new file mode 100644 index 0000000..4fcad9b --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/SmsTimeUtils.java @@ -0,0 +1,148 @@ +package com.dahe.mylibrary.utils; + +import android.content.Context; +import android.os.Handler; +import android.os.Message; +import android.widget.TextView; + +import java.util.Timer; +import java.util.TimerTask; + +/** + * 文件名:SmsTimeUtils + */ +public class SmsTimeUtils { + + /*倒计时时长 单位:秒*/ + private final static int COUNT = 60; + /*当前做*/ + private static int CURR_COUNT = 0; + /*发送验证码*/ + public final static int SETTING_FINANCE_ACCOUNT_TIME = 1; + public final static int WITHDRAW_CASH = 4; + + private static long SETTING_FINANCE_ACCOUNT_TIME_END = 0; + private static long WITHDRAW_CASH_END = 0; + + private static Timer countdownTimer; + private static TextView tvSendCode; + private static Context mContext; + + public static String currPhone;//记录获取验证码的手机号,倒计时结束后清空 + + /** + * 检查是否超过60秒 + * 给当前要从多少开始倒数赋值 + * + * @param first true 表示第一次 false不是 + * @return 是否需要调用startCountdown(TextView textView),主要用于判断在重新打开页,需不需要继续倒计时 + */ + public static boolean check(int type, boolean first) { + long data = System.currentTimeMillis(); + long time = 0; + switch (type) { + case SETTING_FINANCE_ACCOUNT_TIME: + time = SETTING_FINANCE_ACCOUNT_TIME_END; + break; + case WITHDRAW_CASH: + time = WITHDRAW_CASH_END; + break; + } + if (data > time) { + /*主要是区别于是否是第一次进入。第一次进入不需要赋值*/ + if (!first) { + CURR_COUNT = COUNT; + time = data + COUNT * 1000; + switch (type) { + case SETTING_FINANCE_ACCOUNT_TIME: + SETTING_FINANCE_ACCOUNT_TIME_END = time; + break; + case WITHDRAW_CASH: + WITHDRAW_CASH_END = time; + break; + } + } + return false; + } else { + int the_difference = ((int) (time - data)) / 1000; + CURR_COUNT = the_difference; + return true; + } + } + + /** + * 开始倒计时 + * + * @param textView 控制倒计时的view + */ + public static void startCountdown(TextView textView, Context context) { + tvSendCode = textView; + mContext = context; + if (countdownTimer == null) { + countdownTimer = new Timer(); + countdownTimer.schedule(new TimerTask() { + @Override + public void run() { + Message msg = new Message(); + msg.what = CURR_COUNT--; + handler.sendMessage(msg); + } + }, 0, 1000); + } + } + + + /** + * 开始倒计时 + * + * @param textView 控制倒计时的view + */ + public static void startCountdown(TextView textView, Context context,String phone) { + currPhone = phone; + tvSendCode = textView; + mContext = context; + if (countdownTimer == null) { + countdownTimer = new Timer(); + countdownTimer.schedule(new TimerTask() { + @Override + public void run() { + Message msg = new Message(); + msg.what = CURR_COUNT--; + handler.sendMessage(msg); + } + }, 0, 1000); + } + } + + private static Handler handler = new Handler() { + public void handleMessage(Message msg) { + if (msg.what <= 0) { + if (countdownTimer != null) { + countdownTimer.cancel(); + countdownTimer = null; + } + currPhone=""; + tvSendCode.setText("获取验证码"); + tvSendCode.setEnabled(true); + } else { + tvSendCode.setText(msg.what + "s后重新获取"); + tvSendCode.setEnabled(false); + } + super.handleMessage(msg); + } + }; + + + public static void stopCountdown(TextView textView, Context context){ + tvSendCode = textView; + mContext = context; + if (countdownTimer != null) { + countdownTimer.cancel(); + countdownTimer=null; + currPhone=""; + SETTING_FINANCE_ACCOUNT_TIME_END =0; + tvSendCode.setText("获取验证码"); + tvSendCode.setEnabled(true); + } + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/StatusBar.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/StatusBar.java new file mode 100644 index 0000000..d7bcaf4 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/StatusBar.java @@ -0,0 +1,111 @@ +package com.dahe.mylibrary.utils; + +import android.app.Activity; +import android.os.Build; +import android.view.View; +import android.view.Window; + +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; + + +/** + * Utils for status bar + * Created by qiu on 3/29/16. + */ +public class StatusBar { + + //Get alpha color + static int calculateStatusBarColor(int color, int alpha) { + float a = 1 - alpha / 255f; + int red = color >> 16 & 0xff; + int green = color >> 8 & 0xff; + int blue = color & 0xff; + red = (int) (red * a + 0.5); + green = (int) (green * a + 0.5); + blue = (int) (blue * a + 0.5); + return 0xff << 24 | red << 16 | green << 8 | blue; + } + + /** + * set statusBarColor + * @param statusColor color + * @param alpha 0 - 255 + */ + public static void setStatusBarColor(@NonNull Activity activity, @ColorInt int statusColor, int alpha) { + setStatusBarColor(activity, calculateStatusBarColor(statusColor, alpha)); + } + + public static void setStatusBarColor(@NonNull Activity activity, @ColorInt int statusColor) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + StatusBarCompatLollipop.setStatusBarColor(activity, statusColor); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + StatusBarCompatKitKat.setStatusBarColor(activity, statusColor); + } + } + + public static void translucentStatusBar(@NonNull Activity activity) { + translucentStatusBar(activity, false); + } + + /** + * change to full screen mode + * @param hideStatusBarBackground hide status bar alpha Background when SDK > 21, true if hide it + */ + public static void translucentStatusBar(@NonNull Activity activity, boolean hideStatusBarBackground) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + StatusBarCompatLollipop.translucentStatusBar(activity, hideStatusBarBackground); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + StatusBarCompatKitKat.translucentStatusBar(activity); + } + } + + public static void setStatusBarColorForCollapsingToolbar(@NonNull Activity activity, AppBarLayout appBarLayout, CollapsingToolbarLayout collapsingToolbarLayout, + Toolbar toolbar, @ColorInt int statusColor) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + StatusBarCompatLollipop.setStatusBarColorForCollapsingToolbar(activity, appBarLayout, collapsingToolbarLayout, toolbar, statusColor); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + StatusBarCompatKitKat.setStatusBarColorForCollapsingToolbar(activity, appBarLayout, collapsingToolbarLayout, toolbar, statusColor); + } + } + + public static void changeToLightStatusBar(@NonNull Activity activity) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return; + } + if (activity == null) { + return; + } + Window window = activity.getWindow(); + if (window == null) { + return; + } + View decorView = window.getDecorView(); + if (decorView == null) { + return; + } + decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + } + + public static void cancelLightStatusBar(@NonNull Activity activity) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return; + } + if (activity == null) { + return; + } + Window window = activity.getWindow(); + if (window == null) { + return; + } + View decorView = window.getDecorView(); + if (decorView == null) { + return; + } + decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() ^ View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/StatusBarCompatKitKat.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/StatusBarCompatKitKat.java new file mode 100644 index 0000000..5e9c98e --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/StatusBarCompatKitKat.java @@ -0,0 +1,221 @@ +package com.dahe.mylibrary.utils; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.Context; +import android.os.Build; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.FrameLayout; + +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.view.ViewCompat; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; + + +/** + * After kitkat add fake status bar + * Created by qiu on 8/27/16. + */ +@TargetApi(Build.VERSION_CODES.KITKAT) +class StatusBarCompatKitKat { + + private static final String TAG_FAKE_STATUS_BAR_VIEW = "statusBarView"; + private static final String TAG_MARGIN_ADDED = "marginAdded"; + + /** + * node_return statusBar's Height in pixels + */ + private static int getStatusBarHeight(Context context) { + int result = 0; + int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (resId > 0) { + result = context.getResources().getDimensionPixelOffset(resId); + } + return result; + } + + /** + * 1. Add fake statusBarView. + * 2. set tag to statusBarView. + */ + private static View addFakeStatusBarView(Activity activity, int statusBarColor, int statusBarHeight) { + Window window = activity.getWindow(); + ViewGroup mDecorView = (ViewGroup) window.getDecorView(); + + View mStatusBarView = new View(activity); + FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight); + layoutParams.gravity = Gravity.TOP; + mStatusBarView.setLayoutParams(layoutParams); + mStatusBarView.setBackgroundColor(statusBarColor); + mStatusBarView.setTag(TAG_FAKE_STATUS_BAR_VIEW); + + mDecorView.addView(mStatusBarView); + return mStatusBarView; + } + + /** + * use reserved order to remove is more quickly. + */ + private static void removeFakeStatusBarViewIfExist(Activity activity) { + Window window = activity.getWindow(); + ViewGroup mDecorView = (ViewGroup) window.getDecorView(); + + View fakeView = mDecorView.findViewWithTag(TAG_FAKE_STATUS_BAR_VIEW); + if (fakeView != null) { + mDecorView.removeView(fakeView); + } + } + + /** + * add marginTop to simulate set FitsSystemWindow true + */ + private static void addMarginTopToContentChild(View mContentChild, int statusBarHeight) { + if (mContentChild == null) { + return; + } + if (!TAG_MARGIN_ADDED.equals(mContentChild.getTag())) { + FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mContentChild.getLayoutParams(); + lp.topMargin += statusBarHeight; + mContentChild.setLayoutParams(lp); + mContentChild.setTag(TAG_MARGIN_ADDED); + } + } + + /** + * remove marginTop to simulate set FitsSystemWindow false + */ + private static void removeMarginTopOfContentChild(View mContentChild, int statusBarHeight) { + if (mContentChild == null) { + return; + } + if (TAG_MARGIN_ADDED.equals(mContentChild.getTag())) { + FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mContentChild.getLayoutParams(); + lp.topMargin -= statusBarHeight; + mContentChild.setLayoutParams(lp); + mContentChild.setTag(null); + } + } + + /** + * set StatusBarColor + * + * 1. set Window Flag : WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS + * 2. removeFakeStatusBarViewIfExist + * 3. addFakeStatusBarView + * 4. addMarginTopToContentChild + * 5. cancel ContentChild's fitsSystemWindow + */ + static void setStatusBarColor(Activity activity, int statusColor) { + Window window = activity.getWindow(); + window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + + ViewGroup mContentView = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT); + View mContentChild = mContentView.getChildAt(0); + int statusBarHeight = getStatusBarHeight(activity); + + removeFakeStatusBarViewIfExist(activity); + addFakeStatusBarView(activity, statusColor, statusBarHeight); + addMarginTopToContentChild(mContentChild, statusBarHeight); + + if (mContentChild != null) { + ViewCompat.setFitsSystemWindows(mContentChild, false); + } + } + + /** + * translucentStatusBar + * + * 1. set Window Flag : WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS + * 2. removeFakeStatusBarViewIfExist + * 3. removeMarginTopOfContentChild + * 4. cancel ContentChild's fitsSystemWindow + */ + static void translucentStatusBar(Activity activity) { + Window window = activity.getWindow(); + window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + + ViewGroup mContentView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT); + View mContentChild = mContentView.getChildAt(0); + + removeFakeStatusBarViewIfExist(activity); + removeMarginTopOfContentChild(mContentChild, getStatusBarHeight(activity)); + if (mContentChild != null) { + ViewCompat.setFitsSystemWindows(mContentChild, false); + } + } + + /** + * compat for CollapsingToolbarLayout + * + * 1. set Window Flag : WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS + * 2. set FitsSystemWindows for views. + * 3. add Toolbar's height, let it layout from top, then add paddingTop to layout normal. + * 4. removeFakeStatusBarViewIfExist + * 5. removeMarginTopOfContentChild + * 6. add OnOffsetChangedListener to change statusBarView's alpha + */ + static void setStatusBarColorForCollapsingToolbar(Activity activity, final AppBarLayout appBarLayout, final CollapsingToolbarLayout collapsingToolbarLayout, + Toolbar toolbar, int statusColor) { + Window window = activity.getWindow(); + window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + ViewGroup mContentView = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT); + + View mContentChild = mContentView.getChildAt(0); + mContentChild.setFitsSystemWindows(false); + ((View) appBarLayout.getParent()).setFitsSystemWindows(false); + appBarLayout.setFitsSystemWindows(false); + collapsingToolbarLayout.setFitsSystemWindows(false); + collapsingToolbarLayout.getChildAt(0).setFitsSystemWindows(false); + + toolbar.setFitsSystemWindows(false); + if (toolbar.getTag() == null) { + CollapsingToolbarLayout.LayoutParams lp = (CollapsingToolbarLayout.LayoutParams) toolbar.getLayoutParams(); + int statusBarHeight = getStatusBarHeight(activity); + lp.height += statusBarHeight; + toolbar.setLayoutParams(lp); + toolbar.setPadding(toolbar.getPaddingLeft(), toolbar.getPaddingTop() + statusBarHeight, toolbar.getPaddingRight(), toolbar.getPaddingBottom()); + toolbar.setTag(true); + } + + int statusBarHeight = getStatusBarHeight(activity); + removeFakeStatusBarViewIfExist(activity); + removeMarginTopOfContentChild(mContentChild, statusBarHeight); + final View statusView = addFakeStatusBarView(activity, statusColor, statusBarHeight); + + CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams()).getBehavior(); + if (behavior != null && behavior instanceof AppBarLayout.Behavior) { + int verticalOffset = ((AppBarLayout.Behavior) behavior).getTopAndBottomOffset(); + if (Math.abs(verticalOffset) > appBarLayout.getHeight() - collapsingToolbarLayout.getScrimVisibleHeightTrigger()) { + statusView.setAlpha(1f); + } else { + statusView.setAlpha(0f); + } + } else { + statusView.setAlpha(0f); + } + + appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { + @Override + public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { + if (Math.abs(verticalOffset) > appBarLayout.getHeight() - collapsingToolbarLayout.getScrimVisibleHeightTrigger()) { + if (statusView.getAlpha() == 0) { + statusView.animate().cancel(); + statusView.animate().alpha(1f).setDuration(collapsingToolbarLayout.getScrimAnimationDuration()).start(); + } + } else { + if (statusView.getAlpha() == 1) { + statusView.animate().cancel(); + statusView.animate().alpha(0f).setDuration(collapsingToolbarLayout.getScrimAnimationDuration()).start(); + } + } + } + }); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/StatusBarCompatLollipop.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/StatusBarCompatLollipop.java new file mode 100644 index 0000000..c6e64ae --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/StatusBarCompatLollipop.java @@ -0,0 +1,193 @@ +package com.dahe.mylibrary.utils; + +import android.animation.ValueAnimator; +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.Context; +import android.graphics.Color; +import android.os.Build; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; + +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.view.OnApplyWindowInsetsListener; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; + + +/** + * After Lollipop use system method. + * Created by qiu on 8/27/16. + */ +@TargetApi(Build.VERSION_CODES.LOLLIPOP) +class StatusBarCompatLollipop { + + /** + * node_return statusBar's Height in pixels + */ + private static int getStatusBarHeight(Context context) { + int result = 0; + int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (resId > 0) { + result = context.getResources().getDimensionPixelOffset(resId); + } + return result; + } + + /** + * set StatusBarColor + * + * 1. set Flags to call setStatusBarColor + * 2. call setSystemUiVisibility to clear translucentStatusBar's Flag. + * 3. set FitsSystemWindows to false + */ + static void setStatusBarColor(Activity activity, int statusColor) { + Window window = activity.getWindow(); + + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + window.setStatusBarColor(statusColor); + window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); + + ViewGroup mContentView = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT); + View mChildView = mContentView.getChildAt(0); + if (mChildView != null) { + ViewCompat.setFitsSystemWindows(mChildView, false); + ViewCompat.requestApplyInsets(mChildView); + } + } + + /** + * translucentStatusBar(full-screen) + * + * 1. set Flags to full-screen + * 2. set FitsSystemWindows to false + * + * @param hideStatusBarBackground hide statusBar's shadow + */ + static void translucentStatusBar(Activity activity, boolean hideStatusBarBackground) { + Window window = activity.getWindow(); + + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + if (hideStatusBarBackground) { + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + window.setStatusBarColor(Color.TRANSPARENT); + window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + } else { + window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); + } + + ViewGroup mContentView = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT); + View mChildView = mContentView.getChildAt(0); + if (mChildView != null) { + ViewCompat.setFitsSystemWindows(mChildView, false); + ViewCompat.requestApplyInsets(mChildView); + } + } + + /** + * compat for CollapsingToolbarLayout + * + * 1. change to full-screen mode(like translucentStatusBar). + * 2. cancel CollapsingToolbarLayout's WindowInsets, let it layout as normal(now setStatusBarScrimColor is useless). + * 3. set View's FitsSystemWindow to false. + * 4. add Toolbar's height, let it layout from top, then add paddingTop to layout normal. + * 5. change statusBarColor by AppBarLayout's offset. + * 6. add Listener to change statusBarColor + */ + static void setStatusBarColorForCollapsingToolbar(Activity activity, final AppBarLayout appBarLayout, final CollapsingToolbarLayout collapsingToolbarLayout, + Toolbar toolbar, final int statusColor) { + final Window window = activity.getWindow(); + + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + window.setStatusBarColor(Color.TRANSPARENT); + window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); + + ViewCompat.setOnApplyWindowInsetsListener(collapsingToolbarLayout, new OnApplyWindowInsetsListener() { + @Override + public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) { + return insets; + } + }); + + ViewGroup mContentView = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT); + View mChildView = mContentView.getChildAt(0); + if (mChildView != null) { + ViewCompat.setFitsSystemWindows(mChildView, false); + ViewCompat.requestApplyInsets(mChildView); + } + + ((View) appBarLayout.getParent()).setFitsSystemWindows(false); + appBarLayout.setFitsSystemWindows(false); + + toolbar.setFitsSystemWindows(false); + if (toolbar.getTag() == null) { + CollapsingToolbarLayout.LayoutParams lp = (CollapsingToolbarLayout.LayoutParams) toolbar.getLayoutParams(); + int statusBarHeight = getStatusBarHeight(activity); + lp.height += statusBarHeight; + toolbar.setLayoutParams(lp); + toolbar.setPadding(toolbar.getPaddingLeft(), toolbar.getPaddingTop() + statusBarHeight, toolbar.getPaddingRight(), toolbar.getPaddingBottom()); + toolbar.setTag(true); + } + + CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams()).getBehavior(); + if (behavior != null && behavior instanceof AppBarLayout.Behavior) { + int verticalOffset = ((AppBarLayout.Behavior) behavior).getTopAndBottomOffset(); + if (Math.abs(verticalOffset) > appBarLayout.getHeight() - collapsingToolbarLayout.getScrimVisibleHeightTrigger()) { + window.setStatusBarColor(statusColor); + } else { + window.setStatusBarColor(Color.TRANSPARENT); + } + } else { + window.setStatusBarColor(Color.TRANSPARENT); + } + + collapsingToolbarLayout.setFitsSystemWindows(false); + appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { + @Override + public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { + if (Math.abs(verticalOffset) > appBarLayout.getHeight() - collapsingToolbarLayout.getScrimVisibleHeightTrigger()) { + if (window.getStatusBarColor() != statusColor) { + startColorAnimation(window.getStatusBarColor(), statusColor, collapsingToolbarLayout.getScrimAnimationDuration(), window); + } + } else { + if (window.getStatusBarColor() != Color.TRANSPARENT) { + startColorAnimation(window.getStatusBarColor(), Color.TRANSPARENT, collapsingToolbarLayout.getScrimAnimationDuration(), window); + } + } + } + }); + collapsingToolbarLayout.getChildAt(0).setFitsSystemWindows(false); + collapsingToolbarLayout.setStatusBarScrimColor(statusColor); + } + + /** + * use ValueAnimator to change statusBarColor when using collapsingToolbarLayout + */ + static void startColorAnimation(int startColor, int endColor, long duration, final Window window) { + if (sAnimator != null) { + sAnimator.cancel(); + } + sAnimator = ValueAnimator.ofArgb(startColor, endColor) + .setDuration(duration); + sAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + if (window != null) { + window.setStatusBarColor((Integer) valueAnimator.getAnimatedValue()); + } + } + }); + sAnimator.start(); + } + + private static ValueAnimator sAnimator; +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/StringUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/StringUtils.java new file mode 100644 index 0000000..b71df3a --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/StringUtils.java @@ -0,0 +1,99 @@ +package com.dahe.mylibrary.utils; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; + +public class StringUtils { + + public static String byte2hex(byte[] b) { + + String str = ""; + String stmp = ""; + + int length = b.length; + + for (int n = 0; n < length; n++) { + stmp = (Integer.toHexString(b[n] & 0XFF)); + if (stmp.length() == 1) { + str += "0"; + } + str += stmp; + } + + return str.toLowerCase(); + } + + public static String nullToStrTrim(String str) { + + if (str == null) { + str = ""; + } + + return str.trim(); + } + + public static boolean isNotEmpty(String str) { + + return ((str != null) && (str.trim().length() > 0 && !"null".equals(str))); + } + + public static boolean isEmpty(String str) { + + return !isNotEmpty(str); + } + + public static int getRealLength(String str) { + + return getRealLength(str, "utf-8"); + } + + public static int getRealLength(String str, String charsetName) { + + str = nullToStrTrim(str); + + try { + return str.getBytes(charsetName).length; + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return 0; + } + } + public static String encode(String str, String enc) { + + String strEncode = ""; + + try { + if (str != null) + strEncode = URLEncoder.encode(str, enc); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + return strEncode; + } + + public static String decode(String str, String enc) { + + String strDecode = ""; + + try { + if (str != null) + strDecode = URLDecoder.decode(str, enc); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + return strDecode; + } + + public static String encode(String str) { + + return encode(str, "utf-8"); + } + + public static String decode(String str) { + + return decode(str, "utf-8"); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/TimeConstants.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/TimeConstants.java new file mode 100644 index 0000000..d1951da --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/TimeConstants.java @@ -0,0 +1,44 @@ +package com.dahe.mylibrary.utils; + + +import androidx.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + *
+ *     author: Blankj
+ *     blog  : http://blankj.com
+ *     time  : 2017/03/13
+ *     desc  : 时间相关常量
+ * 
+ */ +public final class TimeConstants { + + /** + * 毫秒与毫秒的倍数 + */ + public static final int MSEC = 1; + /** + * 秒与毫秒的倍数 + */ + public static final int SEC = 1000; + /** + * 分与毫秒的倍数 + */ + public static final int MIN = 60000; + /** + * 时与毫秒的倍数 + */ + public static final int HOUR = 3600000; + /** + * 天与毫秒的倍数 + */ + public static final int DAY = 86400000; + + @IntDef({MSEC, SEC, MIN, HOUR, DAY}) + @Retention(RetentionPolicy.SOURCE) + public @interface Unit { + } +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/TimeUtil.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/TimeUtil.java new file mode 100644 index 0000000..0cc51bc --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/TimeUtil.java @@ -0,0 +1,1703 @@ +package com.dahe.mylibrary.utils; + +import android.text.TextUtils; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; + +/** + *
+ *     author: LiJia
+ *     time  : 2021/08/02
+ *     desc  : 时间相关工具类
+ * 
+ */ +public final class TimeUtil { + + /** + *

在工具类中经常使用到工具类的格式化描述,这个主要是一个日期的操作类,所以日志格式主要使用 SimpleDateFormat的定义格式.

+ * 格式的意义如下: 日期和时间模式
+ *

日期和时间格式由日期和时间模式字符串指定。在日期和时间模式字符串中,未加引号的字母 'A' 到 'Z' 和 'a' 到 'z' + * 被解释为模式字母,用来表示日期或时间字符串元素。文本可以使用单引号 (') 引起来,以免进行解释。"''" + * 表示单引号。所有其他字符均不解释;只是在格式化时将它们简单复制到输出字符串,或者在分析时与输入字符串进行匹配。 + *

+ * 定义了以下模式字母(所有其他字符 'A' 到 'Z' 和 'a' 到 'z' 都被保留):
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
字母日期或时间元素表示示例
GEra 标志符TextAD
y Year 1996; 96
M 年中的月份 Month July; Jul; 07
w 年中的周数 Number 27
W 月份中的周数 Number 2
D 年中的天数 Number 189
d 月份中的天数 Number 10
F 月份中的星期 Number 2
E 星期中的天数 Text Tuesday; Tue
a Am/pm 标记 Text PM
H 一天中的小时数(0-23) Number 0
k 一天中的小时数(1-24) Number 24
K am/pm 中的小时数(0-11) Number 0
h am/pm 中的小时数(1-12) Number 12
m 小时中的分钟数 Number 30
s 分钟中的秒数 Number 55
S 毫秒数 Number 978
z 时区 General time zone Pacific Standard Time; PST; GMT-08:00
Z 时区 RFC 822 time zone -0800
+ *
+     *                                             HH:mm    15:44
+     *                                            h:mm a    3:44 下午
+     *                                           HH:mm z    15:44 CST
+     *                                           HH:mm Z    15:44 +0800
+     *                                        HH:mm zzzz    15:44 中国标准时间
+     *                                          HH:mm:ss    15:44:40
+     *                                        yyyy-MM-dd    2016-08-12
+     *                                  yyyy-MM-dd HH:mm    2016-08-12 15:44
+     *                               yyyy-MM-dd HH:mm:ss    2016-08-12 15:44:40
+     *                          yyyy-MM-dd HH:mm:ss zzzz    2016-08-12 15:44:40 中国标准时间
+     *                     EEEE yyyy-MM-dd HH:mm:ss zzzz    星期五 2016-08-12 15:44:40 中国标准时间
+     *                          yyyy-MM-dd HH:mm:ss.SSSZ    2016-08-12 15:44:40.461+0800
+     *                        yyyy-MM-dd'T'HH:mm:ss.SSSZ    2016-08-12T15:44:40.461+0800
+     *                      yyyy.MM.dd G 'at' HH:mm:ss z    2016.08.12 公元 at 15:44:40 CST
+     *                                            K:mm a    3:44 下午
+     *                                  EEE, MMM d, ''yy    星期五, 八月 12, '16
+     *                             hh 'o''clock' a, zzzz    03 o'clock 下午, 中国标准时间
+     *                      yyyyy.MMMMM.dd GGG hh:mm aaa    02016.八月.12 公元 03:44 下午
+     *                        EEE, d MMM yyyy HH:mm:ss Z    星期五, 12 八月 2016 15:44:40 +0800
+     *                                     yyMMddHHmmssZ    160812154440+0800
+     *                        yyyy-MM-dd'T'HH:mm:ss.SSSZ    2016-08-12T15:44:40.461+0800
+     * EEEE 'DATE('yyyy-MM-dd')' 'TIME('HH:mm:ss')' zzzz    星期五 DATE(2016-08-12) TIME(15:44:40) 中国标准时间
+     * 
+ * 注意:SimpleDateFormat不是线程安全的,线程安全需用{@code ThreadLocal} + */ + + private static final DateFormat DEFAULT_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()); + private static final DateFormat DEFAULT_FORMAT2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZSS:SS", Locale.getDefault()); + private static final DateFormat DEFAULT_FORMAT3 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.getDefault()); + + private TimeUtil() { + throw new UnsupportedOperationException("u can't instantiate me..."); + } + + /** + * 将时间戳转为时间字符串 + *

格式为yyyy-MM-dd HH:mm:ss

+ * + * @param millis 毫秒时间戳 + * @return 时间字符串 + */ + public static String millis2String(final long millis) { + return millis2String(millis, DEFAULT_FORMAT); + } + + /** + * 将时间戳转为时间字符串 + *

格式为format

+ * + * @param millis 毫秒时间戳 + * @param format 时间格式 + * @return 时间字符串 + */ + public static String millis2String(final long millis, final DateFormat format) { + return format.format(new Date(millis)); + } + + /** + * 将时间字符串转为时间戳 + *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 时间字符串 + * @return 毫秒时间戳 + */ + public static long string2Millis(final String time) { + if (TextUtils.isEmpty(time)){ + return -1; + } + return string2Millis(time, DEFAULT_FORMAT); + } + + /** + * 将时间字符串转为时间戳 + *

time格式为format

+ * + * @param time 时间字符串 + * @param format 时间格式 + * @return 毫秒时间戳 + */ + public static long string2Millis(final String time, final DateFormat format) { + try { + return format.parse(time).getTime(); + } catch (ParseException e) { + e.printStackTrace(); + } + return -1; + } + + /** + * 将时间字符串转为时间戳 + *

time格式为format

+ * + * @param time 时间字符串 + * @return 毫秒时间戳 + */ + public static String string2String(final String time,final SimpleDateFormat format) { + try { + return date2String(format.parse(time)); +// return DEFAULT_FORMAT.format(DEFAULT_FORMAT2.parse(time).getTime()); + } catch (Exception e) { + e.printStackTrace(); + } + return ""; + } + + /** + * 将时间字符串转为Date类型 + *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 时间字符串 + * @return Date类型 + */ + public static Date string2Date(final String time) { + return string2Date(time, DEFAULT_FORMAT); + } + + /** + * 将时间字符串转为Date类型 + *

time格式为format

+ * + * @param time 时间字符串 + * @param format 时间格式 + * @return Date类型 + */ + public static Date string2Date(final String time, final DateFormat format) { + try { + return format.parse(time); + } catch (ParseException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 将Date类型转为时间字符串 + *

格式为yyyy-MM-dd HH:mm:ss

+ * + * @param date Date类型时间 + * @return 时间字符串 + */ + public static String date2String(final Date date) { + return date2String(date, DEFAULT_FORMAT); + } + + /** + * 将Date类型转为时间字符串 + *

格式为format

+ * + * @param date Date类型时间 + * @param format 时间格式 + * @return 时间字符串 + */ + public static String date2String(final Date date, final DateFormat format) { + return format.format(date); + } + + /** + * 将Date类型转为时间戳 + * + * @param date Date类型时间 + * @return 毫秒时间戳 + */ + public static long date2Millis(final Date date) { + return date.getTime(); + } + + /** + * 将时间戳转为Date类型 + * + * @param millis 毫秒时间戳 + * @return Date类型时间 + */ + public static Date millis2Date(final long millis) { + return new Date(millis); + } + + /** + * 获取两个时间差(单位:unit) + *

time0和time1格式都为yyyy-MM-dd HH:mm:ss

+ * + * @param time0 时间字符串0 + * @param time1 时间字符串1 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return unit时间戳 + */ + public static long getTimeSpan(final String time0, final String time1, @TimeConstants.Unit final int unit) { + return getTimeSpan(time0, time1, DEFAULT_FORMAT, unit); + } + + /** + * 获取两个时间差(单位:unit) + *

time0和time1格式都为format

+ * + * @param time0 时间字符串0 + * @param time1 时间字符串1 + * @param format 时间格式 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return unit时间戳 + */ + public static long getTimeSpan(final String time0, final String time1, final DateFormat format, @TimeConstants.Unit final int unit) { + return millis2TimeSpan(Math.abs(string2Millis(time0, format) - string2Millis(time1, format)), unit); + } + + /** + * 获取两个时间差(单位:unit) + * + * @param date0 Date类型时间0 + * @param date1 Date类型时间1 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return unit时间戳 + */ + public static long getTimeSpan(final Date date0, final Date date1, @TimeConstants.Unit final int unit) { + return millis2TimeSpan(Math.abs(date2Millis(date0) - date2Millis(date1)), unit); + } + + /** + * 获取两个时间差(单位:unit) + * + * @param millis0 毫秒时间戳0 + * @param millis1 毫秒时间戳1 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return unit时间戳 + */ + public static long getTimeSpan(final long millis0, final long millis1, @TimeConstants.Unit final int unit) { + return millis2TimeSpan(Math.abs(millis0 - millis1), unit); + } + + /** + * 获取合适型两个时间差 + *

time0和time1格式都为yyyy-MM-dd HH:mm:ss

+ * + * @param time0 时间字符串0 + * @param time1 时间字符串1 + * @param precision 精度 + *

precision = 0,返回null

+ *

precision = 1,返回天

+ *

precision = 2,返回天和小时

+ *

precision = 3,返回天、小时和分钟

+ *

precision = 4,返回天、小时、分钟和秒

+ *

precision >= 5,返回天、小时、分钟、秒和毫秒

+ * @return 合适型两个时间差 + */ + public static String getFitTimeSpan(final String time0, final String time1, final int precision) { + if (TextUtils.isEmpty(time0)||TextUtils.isEmpty(time1)){ + return ""; + } + return millis2FitTimeSpan(Math.abs(string2Millis(time0, DEFAULT_FORMAT) - string2Millis(time1, DEFAULT_FORMAT)), precision); + } + + /** + * 获取合适型两个时间差 + *

time0和time1格式都为format

+ * + * @param time0 时间字符串0 + * @param time1 时间字符串1 + * @param format 时间格式 + * @param precision 精度 + *

precision = 0,返回null

+ *

precision = 1,返回天

+ *

precision = 2,返回天和小时

+ *

precision = 3,返回天、小时和分钟

+ *

precision = 4,返回天、小时、分钟和秒

+ *

precision >= 5,返回天、小时、分钟、秒和毫秒

+ * @return 合适型两个时间差 + */ + public static String getFitTimeSpan(final String time0, final String time1, final DateFormat format, final int precision) { + return millis2FitTimeSpan(Math.abs(string2Millis(time0, format) - string2Millis(time1, format)), precision); + } + + /** + * 获取合适型两个时间差 + * + * @param date0 Date类型时间0 + * @param date1 Date类型时间1 + * @param precision 精度 + *

precision = 0,返回null

+ *

precision = 1,返回天

+ *

precision = 2,返回天和小时

+ *

precision = 3,返回天、小时和分钟

+ *

precision = 4,返回天、小时、分钟和秒

+ *

precision >= 5,返回天、小时、分钟、秒和毫秒

+ * @return 合适型两个时间差 + */ + public static String getFitTimeSpan(final Date date0, final Date date1, final int precision) { + return millis2FitTimeSpan(Math.abs(date2Millis(date0) - date2Millis(date1)), precision); + } + + /** + * 获取合适型两个时间差 + * + * @param millis0 毫秒时间戳1 + * @param millis1 毫秒时间戳2 + * @param precision 精度 + *

precision = 0,返回null

+ *

precision = 1,返回天

+ *

precision = 2,返回天和小时

+ *

precision = 3,返回天、小时和分钟

+ *

precision = 4,返回天、小时、分钟和秒

+ *

precision >= 5,返回天、小时、分钟、秒和毫秒

+ * @return 合适型两个时间差 + */ + public static String getFitTimeSpan(final long millis0, final long millis1, final int precision) { + return millis2FitTimeSpan(Math.abs(millis0 - millis1), precision); + } + + /** + * 获取当前毫秒时间戳 + * + * @return 毫秒时间戳 + */ + public static long getNowMills() { + return System.currentTimeMillis(); + } + + /** + * 获取当前时间字符串 + * + * @param pattern 格式化时间的格式 + * @return + */ + public static String getNowString(String pattern) { + return millis2String(System.currentTimeMillis(), TextUtils.isEmpty(pattern) ? DEFAULT_FORMAT : new SimpleDateFormat(pattern, Locale.getDefault())); + } + + /** + * 获取当前时间字符串 + *

格式为format

+ * + * @param format 时间格式 + * @return 时间字符串 + */ + public static String getNowString(final DateFormat format) { + return millis2String(System.currentTimeMillis(), format); + } + + /** + * 获取当前Date + * + * @return Date类型时间 + */ + public static Date getNowDate() { + return new Date(); + } + + /** + * 获取与当前时间的差(单位:unit) + *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 时间字符串 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return unit时间戳 + */ + public static long getTimeSpanByNow(final String time, @TimeConstants.Unit final int unit) { + return getTimeSpan(getNowString(""), time, DEFAULT_FORMAT, unit); + } + + /** + * 获取与当前时间的差(单位:unit) + *

time格式为format

+ * + * @param time 时间字符串 + * @param format 时间格式 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return unit时间戳 + */ + public static long getTimeSpanByNow(final String time, final DateFormat format, @TimeConstants.Unit final int unit) { + return getTimeSpan(getNowString(format), time, format, unit); + } + + /** + * 获取与当前时间的差(单位:unit) + * + * @param date Date类型时间 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return unit时间戳 + */ + public static long getTimeSpanByNow(final Date date, @TimeConstants.Unit final int unit) { + return getTimeSpan(new Date(), date, unit); + } + + /** + * 获取与当前时间的差(单位:unit) + * + * @param millis 毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return unit时间戳 + */ + public static long getTimeSpanByNow(final long millis, @TimeConstants.Unit final int unit) { + return getTimeSpan(System.currentTimeMillis(), millis, unit); + } + + /** + * 获取合适型与当前时间的差 + *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 时间字符串 + * @param precision 精度 + *
    + *
  • precision = 0,返回null
  • + *
  • precision = 1,返回天
  • + *
  • precision = 2,返回天和小时
  • + *
  • precision = 3,返回天、小时和分钟
  • + *
  • precision = 4,返回天、小时、分钟和秒
  • + *
  • precision >= 5,返回天、小时、分钟、秒和毫秒
  • + *
+ * @return 合适型与当前时间的差 + */ + public static String getFitTimeSpanByNow(final String time, final int precision) { + return getFitTimeSpan(getNowString(""), time, DEFAULT_FORMAT, precision); + } + + /** + * 获取合适型与当前时间的差 + *

time格式为format

+ * + * @param time 时间字符串 + * @param format 时间格式 + * @param precision 精度 + *
    + *
  • precision = 0,返回null
  • + *
  • precision = 1,返回天
  • + *
  • precision = 2,返回天和小时
  • + *
  • precision = 3,返回天、小时和分钟
  • + *
  • precision = 4,返回天、小时、分钟和秒
  • + *
  • precision >= 5,返回天、小时、分钟、秒和毫秒
  • + *
+ * @return 合适型与当前时间的差 + */ + public static String getFitTimeSpanByNow(final String time, final DateFormat format, final int precision) { + return getFitTimeSpan(getNowString(format), time, format, precision); + } + + /** + * 获取合适型与当前时间的差 + * + * @param date Date类型时间 + * @param precision 精度 + *
    + *
  • precision = 0,返回null
  • + *
  • precision = 1,返回天
  • + *
  • precision = 2,返回天和小时
  • + *
  • precision = 3,返回天、小时和分钟
  • + *
  • precision = 4,返回天、小时、分钟和秒
  • + *
  • precision >= 5,返回天、小时、分钟、秒和毫秒
  • + *
+ * @return 合适型与当前时间的差 + */ + public static String getFitTimeSpanByNow(final Date date, final int precision) { + return getFitTimeSpan(getNowDate(), date, precision); + } + + /** + * 获取合适型与当前时间的差 + * + * @param millis 毫秒时间戳 + * @param precision 精度 + *
    + *
  • precision = 0,返回null
  • + *
  • precision = 1,返回天
  • + *
  • precision = 2,返回天和小时
  • + *
  • precision = 3,返回天、小时和分钟
  • + *
  • precision = 4,返回天、小时、分钟和秒
  • + *
  • precision >= 5,返回天、小时、分钟、秒和毫秒
  • + *
+ * @return 合适型与当前时间的差 + */ + public static String getFitTimeSpanByNow(final long millis, final int precision) { + return getFitTimeSpan(System.currentTimeMillis(), millis, precision); + } + + /** + * 获取友好型与当前时间的差 + *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 时间字符串 + * @return 友好型与当前时间的差 + *
    + *
  • 如果小于1秒钟内,显示刚刚
  • + *
  • 如果在1分钟内,显示XXX秒前
  • + *
  • 如果在1小时内,显示XXX分钟前
  • + *
  • 如果在1小时外的今天内,显示今天15:32
  • + *
  • 如果是昨天的,显示昨天15:32
  • + *
  • 其余显示,2016-10-15
  • + *
  • 时间不合法的情况全部日期和时间信息,如星期六 十月 27 14:21:20 CST 2007
  • + *
+ */ + public static String getFriendlyTimeSpanByNow(final String time) { + return getFriendlyTimeSpanByNow(time, DEFAULT_FORMAT); + } + + /** + * 获取友好型与当前时间的差 + *

time格式为format

+ * + * @param time 时间字符串 + * @param format 时间格式 + * @return 友好型与当前时间的差 + *
    + *
  • 如果小于1秒钟内,显示刚刚
  • + *
  • 如果在1分钟内,显示XXX秒前
  • + *
  • 如果在1小时内,显示XXX分钟前
  • + *
  • 如果在1小时外的今天内,显示今天15:32
  • + *
  • 如果是昨天的,显示昨天15:32
  • + *
  • 其余显示,2016-10-15
  • + *
  • 时间不合法的情况全部日期和时间信息,如星期六 十月 27 14:21:20 CST 2007
  • + *
+ */ + public static String getFriendlyTimeSpanByNow(final String time, final DateFormat format) { + return getFriendlyTimeSpanByNow(string2Millis(time, format)); + } + + /** + * 获取友好型与当前时间的差 + * + * @param date Date类型时间 + * @return 友好型与当前时间的差 + *
    + *
  • 如果小于1秒钟内,显示刚刚
  • + *
  • 如果在1分钟内,显示XXX秒前
  • + *
  • 如果在1小时内,显示XXX分钟前
  • + *
  • 如果在1小时外的今天内,显示今天15:32
  • + *
  • 如果是昨天的,显示昨天15:32
  • + *
  • 其余显示,2016-10-15
  • + *
  • 时间不合法的情况全部日期和时间信息,如星期六 十月 27 14:21:20 CST 2007
  • + *
+ */ + public static String getFriendlyTimeSpanByNow(final Date date) { + return getFriendlyTimeSpanByNow(date.getTime()); + } + + /** + * 获取友好型与当前时间的差 + * + * @param millis 毫秒时间戳 + * @return 友好型与当前时间的差 + *
    + *
  • 如果小于1秒钟内,显示刚刚
  • + *
  • 如果在1分钟内,显示XXX秒前
  • + *
  • 如果在1小时内,显示XXX分钟前
  • + *
  • 如果在1小时外的今天内,显示今天15:32
  • + *
  • 如果是昨天的,显示昨天15:32
  • + *
  • 其余显示,2016-10-15
  • + *
  • 时间不合法的情况全部日期和时间信息,如星期六 十月 27 14:21:20 CST 2007
  • + *
+ */ + public static String getFriendlyTimeSpanByNow(final long millis) { + long now = System.currentTimeMillis(); + long span = now - millis; + if (span < 0) + return String.format("%tc", millis);// U can read http://www.apihome.cn/api/java/Formatter.html to understand it. + if (span < 1000) { + return "刚刚"; + } else if (span < TimeConstants.MIN) { + return String.format(Locale.getDefault(), "%d秒前", span / TimeConstants.SEC); + } else if (span < TimeConstants.HOUR) { + return String.format(Locale.getDefault(), "%d分钟前", span / TimeConstants.MIN); + } + // 获取当天00:00 + long wee = getWeeOfToday(); + if (millis >= wee) { + return String.format("今天%tR", millis); + } else if (millis >= wee - TimeConstants.DAY) { + return String.format("昨天%tR", millis); + } else { + return String.format("%tF", millis); + } + } + + private static long getWeeOfToday() { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.MILLISECOND, 0); + return cal.getTimeInMillis(); + } + + /** + * 获取与给定时间等于时间差的时间戳 + * + * @param millis 给定时间 + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与给定时间等于时间差的时间戳 + */ + public static long getMillis(final long millis, final long timeSpan, @TimeConstants.Unit final int unit) { + return millis + timeSpan2Millis(timeSpan, unit); + } + + /** + * 获取与给定时间等于时间差的时间戳 + *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 给定时间 + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与给定时间等于时间差的时间戳 + */ + public static long getMillis(final String time, final long timeSpan, @TimeConstants.Unit final int unit) { + return getMillis(time, DEFAULT_FORMAT, timeSpan, unit); + } + + /** + * 获取与给定时间等于时间差的时间戳 + *

time格式为format

+ * + * @param time 给定时间 + * @param format 时间格式 + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与给定时间等于时间差的时间戳 + */ + public static long getMillis(final String time, final DateFormat format, final long timeSpan, @TimeConstants.Unit final int unit) { + return string2Millis(time, format) + timeSpan2Millis(timeSpan, unit); + } + + /** + * 获取与给定时间等于时间差的时间戳 + * + * @param date 给定时间 + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与给定时间等于时间差的时间戳 + */ + public static long getMillis(final Date date, final long timeSpan, @TimeConstants.Unit final int unit) { + return date2Millis(date) + timeSpan2Millis(timeSpan, unit); + } + + /** + * 获取与给定时间等于时间差的时间字符串 + *

格式为yyyy-MM-dd HH:mm:ss

+ * + * @param millis 给定时间 + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与给定时间等于时间差的时间字符串 + */ + public static String getString(final long millis, final long timeSpan, @TimeConstants.Unit final int unit) { + return getString(millis, DEFAULT_FORMAT, timeSpan, unit); + } + + /** + * 获取与给定时间等于时间差的时间字符串 + *

格式为format

+ * + * @param millis 给定时间 + * @param format 时间格式 + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与给定时间等于时间差的时间字符串 + */ + public static String getString(final long millis, final DateFormat format, final long timeSpan, @TimeConstants.Unit final int unit) { + return millis2String(millis + timeSpan2Millis(timeSpan, unit), format); + } + + /** + * 获取与给定时间等于时间差的时间字符串 + *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 给定时间 + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与给定时间等于时间差的时间字符串 + */ + public static String getString(final String time, final long timeSpan, @TimeConstants.Unit final int unit) { + return getString(time, DEFAULT_FORMAT, timeSpan, unit); + } + + /** + * 获取与给定时间等于时间差的时间字符串 + *

格式为format

+ * + * @param time 给定时间 + * @param format 时间格式 + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与给定时间等于时间差的时间字符串 + */ + public static String getString(final String time, final DateFormat format, final long timeSpan, @TimeConstants.Unit final int unit) { + return millis2String(string2Millis(time, format) + timeSpan2Millis(timeSpan, unit), format); + } + + /** + * 获取与给定时间等于时间差的时间字符串 + *

格式为yyyy-MM-dd HH:mm:ss

+ * + * @param date 给定时间 + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与给定时间等于时间差的时间字符串 + */ + public static String getString(final Date date, final long timeSpan, @TimeConstants.Unit final int unit) { + return getString(date, DEFAULT_FORMAT, timeSpan, unit); + } + + /** + * 获取与给定时间等于时间差的时间字符串 + *

格式为format

+ * + * @param date 给定时间 + * @param format 时间格式 + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与给定时间等于时间差的时间字符串 + */ + public static String getString(final Date date, final DateFormat format, final long timeSpan, @TimeConstants.Unit final int unit) { + return millis2String(date2Millis(date) + timeSpan2Millis(timeSpan, unit), format); + } + + /** + * 获取与给定时间等于时间差的Date + * + * @param millis 给定时间 + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与给定时间等于时间差的Date + */ + public static Date getDate(final long millis, final long timeSpan, @TimeConstants.Unit final int unit) { + return millis2Date(millis + timeSpan2Millis(timeSpan, unit)); + } + + /** + * 获取与给定时间等于时间差的Date + *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 给定时间 + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与给定时间等于时间差的Date + */ + public static Date getDate(final String time, final long timeSpan, @TimeConstants.Unit final int unit) { + return getDate(time, DEFAULT_FORMAT, timeSpan, unit); + } + + /** + * 获取与给定时间等于时间差的Date + *

格式为format

+ * + * @param time 给定时间 + * @param format 时间格式 + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与给定时间等于时间差的Date + */ + public static Date getDate(final String time, final DateFormat format, final long timeSpan, @TimeConstants.Unit final int unit) { + return millis2Date(string2Millis(time, format) + timeSpan2Millis(timeSpan, unit)); + } + + /** + * 获取与给定时间等于时间差的Date + * + * @param date 给定时间 + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与给定时间等于时间差的Date + */ + public static Date getDate(final Date date, final long timeSpan, @TimeConstants.Unit final int unit) { + return millis2Date(date2Millis(date) + timeSpan2Millis(timeSpan, unit)); + } + + /** + * 获取与当前时间等于时间差的时间戳 + * + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与当前时间等于时间差的时间戳 + */ + public static long getMillisByNow(final long timeSpan, @TimeConstants.Unit final int unit) { + return getMillis(getNowMills(), timeSpan, unit); + } + + /** + * 获取与当前时间等于时间差的时间字符串 + *

格式为yyyy-MM-dd HH:mm:ss

+ * + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与当前时间等于时间差的时间字符串 + */ + public static String getStringByNow(final long timeSpan, @TimeConstants.Unit final int unit) { + return getStringByNow(timeSpan, DEFAULT_FORMAT, unit); + } + + /** + * 获取与当前时间等于时间差的时间字符串 + *

格式为format

+ * + * @param timeSpan 时间差的毫秒时间戳 + * @param format 时间格式 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与当前时间等于时间差的时间字符串 + */ + public static String getStringByNow(final long timeSpan, final DateFormat format, @TimeConstants.Unit final int unit) { + return getString(getNowMills(), format, timeSpan, unit); + } + + /** + * 获取与当前时间等于时间差的Date + * + * @param timeSpan 时间差的毫秒时间戳 + * @param unit 单位类型 + *
    + *
  • {@link TimeConstants#MSEC}: 毫秒
  • + *
  • {@link TimeConstants#SEC }: 秒
  • + *
  • {@link TimeConstants#MIN }: 分
  • + *
  • {@link TimeConstants#HOUR}: 小时
  • + *
  • {@link TimeConstants#DAY }: 天
  • + *
+ * @return 与当前时间等于时间差的Date + */ + public static Date getDateByNow(final long timeSpan, @TimeConstants.Unit final int unit) { + return getDate(getNowMills(), timeSpan, unit); + } + + /** + * 判断是否今天 + *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 时间字符串 + * @return {@code true}: 是
{@code false}: 否 + */ + public static boolean isToday(final String time) { + return isToday(string2Millis(time, DEFAULT_FORMAT)); + } + + /** + * 判断是否今天 + *

time格式为format

+ * + * @param time 时间字符串 + * @param format 时间格式 + * @return {@code true}: 是
{@code false}: 否 + */ + public static boolean isToday(final String time, final DateFormat format) { + return isToday(string2Millis(time, format)); + } + + /** + * 判断是否今天 + * + * @param date Date类型时间 + * @return {@code true}: 是
{@code false}: 否 + */ + public static boolean isToday(final Date date) { + return isToday(date.getTime()); + } + + /** + * 判断是否今天 + * + * @param millis 毫秒时间戳 + * @return {@code true}: 是
{@code false}: 否 + */ + public static boolean isToday(final long millis) { + long wee = getWeeOfToday(); + return millis >= wee && millis < wee + TimeConstants.DAY; + } + + /** + * 判断是否闰年 + *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 时间字符串 + * @return {@code true}: 闰年
{@code false}: 平年 + */ + public static boolean isLeapYear(final String time) { + return isLeapYear(string2Date(time, DEFAULT_FORMAT)); + } + + /** + * 判断是否闰年 + *

time格式为format

+ * + * @param time 时间字符串 + * @param format 时间格式 + * @return {@code true}: 闰年
{@code false}: 平年 + */ + public static boolean isLeapYear(final String time, final DateFormat format) { + return isLeapYear(string2Date(time, format)); + } + + /** + * 判断是否闰年 + * + * @param date Date类型时间 + * @return {@code true}: 闰年
{@code false}: 平年 + */ + public static boolean isLeapYear(final Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int year = cal.get(Calendar.YEAR); + return isLeapYear(year); + } + + /** + * 判断是否闰年 + * + * @param millis 毫秒时间戳 + * @return {@code true}: 闰年
{@code false}: 平年 + */ + public static boolean isLeapYear(final long millis) { + return isLeapYear(millis2Date(millis)); + } + + /** + * 判断是否闰年 + * + * @param year 年份 + * @return {@code true}: 闰年
{@code false}: 平年 + */ + public static boolean isLeapYear(final int year) { + return year % 4 == 0 && year % 100 != 0 || year % 400 == 0; + } + + /** + * 获取中式星期 + *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 时间字符串 + * @return 中式星期 + */ + public static String getChineseWeek(final String time) { + return getChineseWeek(string2Date(time, DEFAULT_FORMAT)); + } + + /** + * 获取当前中式时间 + * + * @return + */ + public static String getChineseNowWeek() { + return getChineseWeek(string2Date(getNowString(""), DEFAULT_FORMAT)); + } + + /** + * 获取中式星期 + *

time格式为format

+ * + * @param time 时间字符串 + * @param format 时间格式 + * @return 中式星期 + */ + public static String getChineseWeek(final String time, final DateFormat format) { + return getChineseWeek(string2Date(time, format)); + } + + /** + * 获取中式星期 + * + * @param date Date类型时间 + * @return 中式星期 + */ + public static String getChineseWeek(final Date date) { + return new SimpleDateFormat("E", Locale.CHINA).format(date); + } + + /** + * 获取中式星期 + * + * @param millis 毫秒时间戳 + * @return 中式星期 + */ + public static String getChineseWeek(final long millis) { + return getChineseWeek(new Date(millis)); + } + + /** + * 获取美式星期 + *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 时间字符串 + * @return 美式星期 + */ + public static String getUSWeek(final String time) { + return getUSWeek(string2Date(time, DEFAULT_FORMAT)); + } + + /** + * 获取美式星期 + *

time格式为format

+ * + * @param time 时间字符串 + * @param format 时间格式 + * @return 美式星期 + */ + public static String getUSWeek(final String time, final DateFormat format) { + return getUSWeek(string2Date(time, format)); + } + + /** + * 获取美式星期 + * + * @param date Date类型时间 + * @return 美式星期 + */ + public static String getUSWeek(final Date date) { + return new SimpleDateFormat("EEEE", Locale.US).format(date); + } + + /** + * 获取美式星期 + * + * @param millis 毫秒时间戳 + * @return 美式星期 + */ + public static String getUSWeek(final long millis) { + return getUSWeek(new Date(millis)); + } + + /** + * 获取星期索引 + *

注意:周日的Index才是1,周六为7

+ *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 时间字符串 + * @return 1...7 + * @see Calendar#SUNDAY + * @see Calendar#MONDAY + * @see Calendar#TUESDAY + * @see Calendar#WEDNESDAY + * @see Calendar#THURSDAY + * @see Calendar#FRIDAY + * @see Calendar#SATURDAY + */ + public static int getWeekIndex(final String time) { + return getWeekIndex(string2Date(time, DEFAULT_FORMAT)); + } + + /** + * 获取星期索引 + *

注意:周日的Index才是1,周六为7

+ *

time格式为format

+ * + * @param time 时间字符串 + * @param format 时间格式 + * @return 1...7 + * @see Calendar#SUNDAY + * @see Calendar#MONDAY + * @see Calendar#TUESDAY + * @see Calendar#WEDNESDAY + * @see Calendar#THURSDAY + * @see Calendar#FRIDAY + * @see Calendar#SATURDAY + */ + public static int getWeekIndex(final String time, final DateFormat format) { + return getWeekIndex(string2Date(time, format)); + } + + /** + * 获取星期索引 + *

注意:周日的Index才是1,周六为7

+ * + * @param date Date类型时间 + * @return 1...7 + * @see Calendar#SUNDAY + * @see Calendar#MONDAY + * @see Calendar#TUESDAY + * @see Calendar#WEDNESDAY + * @see Calendar#THURSDAY + * @see Calendar#FRIDAY + * @see Calendar#SATURDAY + */ + public static int getWeekIndex(final Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + return cal.get(Calendar.DAY_OF_WEEK); + } + + /** + * 获取星期索引 + *

注意:周日的Index才是1,周六为7

+ * + * @param millis 毫秒时间戳 + * @return 1...7 + * @see Calendar#SUNDAY + * @see Calendar#MONDAY + * @see Calendar#TUESDAY + * @see Calendar#WEDNESDAY + * @see Calendar#THURSDAY + * @see Calendar#FRIDAY + * @see Calendar#SATURDAY + */ + public static int getWeekIndex(final long millis) { + return getWeekIndex(millis2Date(millis)); + } + + /** + * 获取月份中的第几周 + *

注意:国外周日才是新的一周的开始

+ *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 时间字符串 + * @return 1...5 + */ + public static int getWeekOfMonth(final String time) { + return getWeekOfMonth(string2Date(time, DEFAULT_FORMAT)); + } + + /** + * 获取月份中的第几周 + *

注意:国外周日才是新的一周的开始

+ *

time格式为format

+ * + * @param time 时间字符串 + * @param format 时间格式 + * @return 1...5 + */ + public static int getWeekOfMonth(final String time, final DateFormat format) { + return getWeekOfMonth(string2Date(time, format)); + } + + /** + * 获取月份中的第几周 + *

注意:国外周日才是新的一周的开始

+ * + * @param date Date类型时间 + * @return 1...5 + */ + public static int getWeekOfMonth(final Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + return cal.get(Calendar.WEEK_OF_MONTH); + } + + /** + * 获取月份中的第几周 + *

注意:国外周日才是新的一周的开始

+ * + * @param millis 毫秒时间戳 + * @return 1...5 + */ + public static int getWeekOfMonth(final long millis) { + return getWeekOfMonth(millis2Date(millis)); + } + + /** + * 获取年份中的第几周 + *

注意:国外周日才是新的一周的开始

+ *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 时间字符串 + * @return 1...54 + */ + public static int getWeekOfYear(final String time) { + return getWeekOfYear(string2Date(time, DEFAULT_FORMAT)); + } + + /** + * 获取年份中的第几周 + *

注意:国外周日才是新的一周的开始

+ *

time格式为format

+ * + * @param time 时间字符串 + * @param format 时间格式 + * @return 1...54 + */ + public static int getWeekOfYear(final String time, final DateFormat format) { + return getWeekOfYear(string2Date(time, format)); + } + + /** + * 获取年份中的第几周 + *

注意:国外周日才是新的一周的开始

+ * + * @param date Date类型时间 + * @return 1...54 + */ + public static int getWeekOfYear(final Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + return cal.get(Calendar.WEEK_OF_YEAR); + } + + /** + * 获取年份中的第几周 + *

注意:国外周日才是新的一周的开始

+ * + * @param millis 毫秒时间戳 + * @return 1...54 + */ + public static int getWeekOfYear(final long millis) { + return getWeekOfYear(millis2Date(millis)); + } + + private static final String[] CHINESE_ZODIAC = {"猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊"}; + + /** + * 获取生肖 + *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 时间字符串 + * @return 生肖 + */ + public static String getChineseZodiac(final String time) { + return getChineseZodiac(string2Date(time, DEFAULT_FORMAT)); + } + + /** + * 获取生肖 + *

time格式为format

+ * + * @param time 时间字符串 + * @param format 时间格式 + * @return 生肖 + */ + public static String getChineseZodiac(final String time, final DateFormat format) { + return getChineseZodiac(string2Date(time, format)); + } + + /** + * 获取生肖 + * + * @param date Date类型时间 + * @return 生肖 + */ + public static String getChineseZodiac(final Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + return CHINESE_ZODIAC[cal.get(Calendar.YEAR) % 12]; + } + + /** + * 获取生肖 + * + * @param millis 毫秒时间戳 + * @return 生肖 + */ + public static String getChineseZodiac(final long millis) { + return getChineseZodiac(millis2Date(millis)); + } + + /** + * 获取生肖 + * + * @param year 年 + * @return 生肖 + */ + public static String getChineseZodiac(final int year) { + return CHINESE_ZODIAC[year % 12]; + } + + private static final String[] ZODIAC = {"水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "魔羯座"}; + private static final int[] ZODIAC_FLAGS = {20, 19, 21, 21, 21, 22, 23, 23, 23, 24, 23, 22}; + + /** + * 获取星座 + *

time格式为yyyy-MM-dd HH:mm:ss

+ * + * @param time 时间字符串 + * @return 生肖 + */ + public static String getZodiac(final String time) { + return getZodiac(string2Date(time, DEFAULT_FORMAT)); + } + + /** + * 获取星座 + *

time格式为format

+ * + * @param time 时间字符串 + * @param format 时间格式 + * @return 生肖 + */ + public static String getZodiac(final String time, final DateFormat format) { + return getZodiac(string2Date(time, format)); + } + + /** + * 获取星座 + * + * @param date Date类型时间 + * @return 星座 + */ + public static String getZodiac(final Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int month = cal.get(Calendar.MONTH) + 1; + int day = cal.get(Calendar.DAY_OF_MONTH); + return getZodiac(month, day); + } + + /** + * 获取星座 + * + * @param millis 毫秒时间戳 + * @return 星座 + */ + public static String getZodiac(final long millis) { + return getZodiac(millis2Date(millis)); + } + + /** + * 获取星座 + * + * @param month 月 + * @param day 日 + * @return 星座 + */ + public static String getZodiac(final int month, final int day) { + return ZODIAC[day >= ZODIAC_FLAGS[month - 1] + ? month - 1 + : (month + 10) % 12]; + } + + private static long timeSpan2Millis(final long timeSpan, @TimeConstants.Unit final int unit) { + return timeSpan * unit; + } + + private static long millis2TimeSpan(final long millis, @TimeConstants.Unit final int unit) { + return millis / unit; + } + + public static String millis2FitTimeSpan(long millis, int precision) { + if (millis < 0 || precision <= 0) return null; + precision = Math.min(precision, 5); + String[] units = {"天", "时", "分", "秒", "毫秒"}; + if (millis == 0) return 0 + units[precision - 1]; + StringBuilder sb = new StringBuilder(); + int[] unitLen = {86400000, 3600000, 60000, 1000, 1}; + for (int i = 0; i < precision; i++) { + if (millis >= unitLen[i]) { + long mode = millis / unitLen[i]; + millis -= mode * unitLen[i]; + sb.append(mode).append(units[i]); + } + } + return sb.toString(); + } + + + /** + * 比较时间大小 + * + * @param nowDate + * @param compareDate + * @return + */ + public static boolean compareDate(String nowDate, String compareDate) { + DateFormat df = DEFAULT_FORMAT; + try { + Date now = df.parse(nowDate); + Date compare = df.parse(compareDate); + if (now.after(compare)) { + return true; + } else { + return false; + } + } catch (ParseException e) { + e.printStackTrace(); + return false; + } + } + + /** + * 比较时间大小 + * + * @param nowDate + * @param compareDate + * @return + */ + public static boolean compareDate(String nowDate, String compareDate,DateFormat format) { + DateFormat df = format; + try { + Date now = df.parse(nowDate); + Date compare = df.parse(compareDate); + if (now.after(compare)) { + return true; + } else { + return false; + } + } catch (ParseException e) { + e.printStackTrace(); + return false; + } + } +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/TimingX.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/TimingX.java new file mode 100644 index 0000000..df631dc --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/TimingX.java @@ -0,0 +1,145 @@ +package com.dahe.mylibrary.utils; + +import android.os.Handler; +import android.os.Message; +import android.widget.TextView; + +import java.util.ArrayList; + +import io.reactivex.rxjava3.annotations.NonNull; + +public class TimingX { + + private volatile static TimingX sTimingX; + + private static int sSecond = 0, sStatus = TimingEnum.STOP.val; + + private static final Handler sHandler = new TimingXHandler(); + + private static final ArrayList timingViews = new ArrayList<>(8); + + private static String time = ""; + + private TimingX() { + } + + public static TimingX builder(){ + if(sTimingX == null){ + synchronized (TimingX.class){ + if(sTimingX == null){ + sTimingX = new TimingX(); + } + } + } + return sTimingX; + } + + private static class TimingXHandler extends Handler { + @Override + public void handleMessage(@NonNull Message msg) { + int status = msg.what; + if (status == TimingEnum.START.val) { + sSecond += 1; + time = format(sSecond); + sHandler.sendEmptyMessageDelayed(status, 1000); + } else if (status == TimingEnum.STOP.val) { + time = format(sSecond); + } + showTime(); + } + } + + private static void showTime(){ + for (TextView timingView : timingViews) { + timingView.setText(time); + } + } + + public int getStatus(){ + return sStatus; + } + + enum TimingEnum { + STOP(0), // 停止计时 + START(1), // 开始计时 + CLEAR(-1); // 清除计时 + int val; + TimingEnum(int val){ + this.val = val; + } + } + + /** + * 添加需要计时的 view + * @param view + * @return + */ + public TimingX add(TextView view){ + if(!timingViews.contains(view)){ + timingViews.add(view); + } + return sTimingX; + } + + /** + * 移除不需要计时的 view + * @param view + * @return + */ + public TimingX remove(TextView view){ + timingViews.remove(view); + return sTimingX; + } + + /** + * 开始计时 + */ + public void start(){ + if(sStatus == TimingEnum.STOP.val){ + sStatus = TimingEnum.START.val; + sHandler.sendEmptyMessageDelayed(sStatus, 1000); + } + } + + /** + * 停止计时 + */ + public void stop(){ + if(sStatus == TimingEnum.START.val){ + sStatus = TimingEnum.STOP.val; + sHandler.removeMessages(TimingEnum.START.val); + sHandler.sendEmptyMessage(sStatus); + } + } + + /** + * 销毁 handler + */ + public void destroy(){ + sStatus = TimingEnum.STOP.val; + sSecond = 0; + sHandler.removeMessages(TimingEnum.START.val); + timingViews.clear(); + } + + /** + * 将秒转化为分秒的形式(00:00) + * @param second + * @return + */ + public static String format(int second) { + StringBuilder sb = new StringBuilder(); + int minutes = second / 60; + int sec = second % 60; + if(minutes < 10){ + sb.append(0); + } + sb.append(minutes); + sb.append(":"); + if(sec < 10){ + sb.append(0); + } + sb.append(sec); + return sb.toString(); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/ToastUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/ToastUtils.java new file mode 100644 index 0000000..5b03d72 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/ToastUtils.java @@ -0,0 +1,37 @@ +package com.dahe.mylibrary.utils; + +import android.content.Context; +import android.text.TextUtils; +import android.widget.Toast; + +/** + * Created by Administrator on 2017/11/28 0028. + */ + +public class ToastUtils { + public static Toast mToast = null; + + public static void showToast(Context mContext, String message) { + if (!TextUtils.isEmpty(message)) { + +// if ( mToast != null) { +// mToast.cancel(); +// } +// mToast = Toast.makeText(mContext, message, Toast.LENGTH_SHORT); +// mToast.show(); + + if (mToast == null) { + mToast = Toast.makeText(mContext, message, Toast.LENGTH_SHORT); + } else { + mToast.setText(message); + } + mToast.show(); + } + } + + public static void cancelToast(){ + if (mToast!=null) + mToast.cancel(); + } + +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/VersionUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/VersionUtils.java new file mode 100644 index 0000000..b03f60a --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/VersionUtils.java @@ -0,0 +1,181 @@ +package com.dahe.mylibrary.utils; + +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.text.TextUtils; +import android.text.method.ScrollingMovementMethod; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.TextView; + +import androidx.annotation.Nullable; + +import com.allenliu.versionchecklib.core.http.HttpParams; +import com.allenliu.versionchecklib.core.http.HttpRequestMethod; +import com.allenliu.versionchecklib.v2.AllenVersionChecker; +import com.allenliu.versionchecklib.v2.builder.DownloadBuilder; +import com.allenliu.versionchecklib.v2.builder.RequestVersionBuilder; +import com.allenliu.versionchecklib.v2.builder.UIData; +import com.allenliu.versionchecklib.v2.callback.CustomDownloadingDialogListener; +import com.allenliu.versionchecklib.v2.callback.CustomVersionDialogListener; +import com.allenliu.versionchecklib.v2.callback.RequestVersionListener; +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.bean.VersionBean; +import com.dahe.mylibrary.dialog.VersionDialog; +import com.dahe.mylibrary.net.CommonResponseBean; +import com.dahe.mylibrary.net.JsonUtils; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; + +public class VersionUtils { + + + private static class SingletonHolder { + private static final VersionUtils INSTANCE = new VersionUtils(); + } + + private VersionUtils() { + } + + public static final VersionUtils getInstance() { + return SingletonHolder.INSTANCE; + } + + public void checkVersion(Context ctx, String api,boolean isShow) { + HttpParams httpParams = new HttpParams(); + httpParams.put("appType", "1"); + DownloadBuilder request = AllenVersionChecker + .getInstance() + .requestVersion() + .setRequestMethod(HttpRequestMethod.GET) + .setRequestUrl(api) + .setRequestParams(httpParams) + .request(new RequestVersionListener() { + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public UIData onRequestVersionSuccess(DownloadBuilder downloadBuilder, String result) { + try { + if (StringUtils.isEmpty(result)) + return null; + Type type = new TypeToken>() { + }.getType(); + CommonResponseBean o = JsonUtils.getInstance().fromJson(result, type); + VersionBean.ParamsDao data = o.getData().getData(); + if ("1".equals(data.getUpdateType())) { + downloadBuilder.setForceRedownload(true); + }else{ + downloadBuilder.setForceRedownload(false); + } + if (AppUtils.getAppVersionCode() < data.getVersion()) { + UIData uiData = UIData.create(); + uiData.setTitle(data.getVersionName()); + uiData.setDownloadUrl(data.getApkUrl()); + uiData.setContent(data.getIntroduce()); + return uiData; + } + if (isShow){ + ToastUtils.showToast(ctx,"当前已是最新版本啊!"); + } + return null; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + public void onRequestVersionFailure(String message) { + + } + }); + + request.setCustomVersionDialogListener(createCustomDialogTwo(request)); + request.setCustomDownloadingDialogListener(createCustomDownloadingDialog(ctx)).executeMission(ctx); + } + + private CustomVersionDialogListener createCustomDialogTwo(DownloadBuilder request) { + return (context, versionBundle) -> { + VersionDialog baseDialog = new VersionDialog(context, R.style.BaseDialog, R.layout.custom_dialog_two_layout2); + TextView textView = baseDialog.findViewById(R.id.tv_msg); + TextView tvVersion = baseDialog.findViewById(R.id.tvVersion); + tvVersion.setText(request.getVersionBundle().getTitle()+" 版本更新"); + textView.setMovementMethod(ScrollingMovementMethod.getInstance()); + RequestVersionBuilder requestVersionBuilder = request.getRequestVersionBuilder(); +// TextView tvTitle = baseDialog.findViewById(R.id.tv_title); + baseDialog.findViewById(R.id.close).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + boolean forceRedownload = request.isForceRedownload(); + if (forceRedownload){ + ToastUtils.showToast(context,"请更新版本"); + }else{ + baseDialog.cancel(); + baseDialog.dismiss(); + AllenVersionChecker.getInstance().cancelAllMission(); + } + + } + }); +// textView.setText(versionBundle.getContent()); + textView.setText(versionBundle.getContent()); + baseDialog.setCanceledOnTouchOutside(request.isForceRedownload()?false:true); + baseDialog.setOnKeyListener(new DialogInterface.OnKeyListener() { + @Override + public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { + if (KeyEvent.KEYCODE_BACK==event.getKeyCode()&&request.isForceRedownload()){ + ToastUtils.showToast(context,"请更新版本"); + return true; + } + return false; + } + }); + baseDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + + } + }); + return baseDialog; + }; + } + + + /** + * 自定义下载中对话框,下载中会连续回调此方法 updateUI + * 务必用库传回来的context 实例化你的dialog + * + * @param ctx + * @return + */ + private CustomDownloadingDialogListener createCustomDownloadingDialog(Context ctx) { + return new CustomDownloadingDialogListener() { + @Override + public Dialog getCustomDownloadingDialog(Context context, int progress, UIData versionBundle) { + VersionDialog baseDialog = new VersionDialog(context, R.style.BaseDialog, R.layout.dialog_download_layout); + return baseDialog; + } + + @Override + public void updateUI(Dialog dialog, int progress, UIData versionBundle) { + TextView tvProgress = dialog.findViewById(R.id.tv_progress); + ProgressBar progressBar = dialog.findViewById(R.id.pb); + progressBar.setProgress(progress); + tvProgress.setText(ctx.getString(R.string.versionchecklib_progress, progress)); + } + }; + } + +// private NotificationBuilder createCustomNotification(Context ctx) { +// return NotificationBuilder.create() +// .setRingtone(true) +// .setIcon(R.mipmap.) +// .setTicker("custom_ticker") +// .setContentTitle("custom title") +// .setContentText(ctx.getString(R.string.custom_content_text)); +// } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/wapper/SelectSimAdapter.java b/mylibrary/src/main/java/com/dahe/mylibrary/wapper/SelectSimAdapter.java new file mode 100644 index 0000000..6302e3e --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/wapper/SelectSimAdapter.java @@ -0,0 +1,37 @@ +package com.dahe.mylibrary.wapper; + +import android.widget.TextView; + +import androidx.annotation.Nullable; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.dahe.mylibrary.R; + +import java.util.List; + +public class SelectSimAdapter extends BaseQuickAdapter { + private String selectString = ""; + + + public SelectSimAdapter(int layoutResId, @Nullable List data, String selectString) { + super(R.layout.item_select, data); + this.selectString = selectString; + } + + @Override + protected void convert(BaseViewHolder helper, String item) { + helper.setText(R.id.tv_content,item); + TextView tv = helper.getView(R.id.tv_content); + if (item.equals(selectString)){ + tv.setSelected(true); + }else{ + tv.setSelected(false); + } + + } + + public void setSelect(String selectString){ + this.selectString = selectString; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/weight/AttachButton.java b/mylibrary/src/main/java/com/dahe/mylibrary/weight/AttachButton.java new file mode 100644 index 0000000..6051134 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/weight/AttachButton.java @@ -0,0 +1,157 @@ +package com.dahe.mylibrary.weight; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.BounceInterpolator; + +import androidx.annotation.Nullable; + +import com.dahe.mylibrary.R; +/** + * 自定义View实现拖动并自动吸边效果 + *

+ * 处理滑动和贴边 {@link #onTouchEvent(MotionEvent)} + * 处理事件分发 {@link #dispatchTouchEvent(MotionEvent)} + *

+ * + * @attr customIsAttach //是否需要自动吸边 + * @attr customIsDrag //是否可拖曳 + */ +public class AttachButton extends View { + private float mLastRawX; + private float mLastRawY; + private final String TAG = "AttachButton"; + private boolean isDrug = false; + private int mRootMeasuredWidth = 0; + private int mRootMeasuredHeight = 0; + private int mRootTopY = 0; + private boolean customIsAttach; + private boolean customIsDrag; + + public AttachButton(Context context) { + this(context, null); + } + + public AttachButton(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public AttachButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initAttrs(context, attrs); + } + + /** + * 初始化自定义属性 + */ + private void initAttrs(Context context, AttributeSet attrs) { + TypedArray mTypedAttay = context.obtainStyledAttributes(attrs, R.styleable.AttachButton); + customIsAttach = mTypedAttay.getBoolean(R.styleable.AttachButton_customIsAttach, true); + customIsDrag = mTypedAttay.getBoolean(R.styleable.AttachButton_customIsDrag, true); + mTypedAttay.recycle(); + } + + @Override + public boolean dispatchTouchEvent(MotionEvent event) { + super.dispatchTouchEvent(event); + return true; + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + //判断是否需要滑动 + if (customIsDrag) { + //当前手指的坐标 + float mRawX = ev.getRawX(); + float mRawY = ev.getRawY(); + switch (ev.getAction()) { + case MotionEvent.ACTION_DOWN://手指按下 + isDrug = false; + //记录按下的位置 + mLastRawX = mRawX; + mLastRawY = mRawY; + ViewGroup mViewGroup = (ViewGroup) getParent(); + if (mViewGroup != null) { + int[] location = new int[2]; + mViewGroup.getLocationInWindow(location); + //获取父布局的高度 + mRootMeasuredHeight = mViewGroup.getMeasuredHeight(); + mRootMeasuredWidth = mViewGroup.getMeasuredWidth(); + //获取父布局顶点的坐标 + mRootTopY = location[1]; + } + break; + case MotionEvent.ACTION_MOVE://手指滑动 + if (mRawX >= 0 && mRawX <= mRootMeasuredWidth && mRawY >= mRootTopY && mRawY <= (mRootMeasuredHeight + mRootTopY)) { + //手指X轴滑动距离 + float differenceValueX = mRawX - mLastRawX; + //手指Y轴滑动距离 + float differenceValueY = mRawY - mLastRawY; + //判断是否为拖动操作 + if (!isDrug) { + if (Math.sqrt(differenceValueX * differenceValueX + differenceValueY * differenceValueY) < 2) { + isDrug = false; + } else { + isDrug = true; + } + } + //获取手指按下的距离与控件本身X轴的距离 + float ownX = getX(); + //获取手指按下的距离与控件本身Y轴的距离 + float ownY = getY(); + //理论中X轴拖动的距离 + float endX = ownX + differenceValueX; + //理论中Y轴拖动的距离 + float endY = ownY + differenceValueY; + //X轴可以拖动的最大距离 + float maxX = mRootMeasuredWidth - getWidth(); + //Y轴可以拖动的最大距离 + float maxY = mRootMeasuredHeight - getHeight(); + //X轴边界限制 + endX = endX < 0 ? 0 : endX > maxX ? maxX : endX; + //Y轴边界限制 + endY = endY < 0 ? 0 : endY > maxY ? maxY : endY; + //开始移动 + setX(endX); + setY(endY); + //记录位置 + mLastRawX = mRawX; + mLastRawY = mRawY; + } + + break; + case MotionEvent.ACTION_UP://手指离开 + //根据自定义属性判断是否需要贴边 + if (customIsAttach) { + //判断是否为点击事件 + if (isDrug) { + float center = mRootMeasuredWidth / 2; + //自动贴边 + if (mLastRawX <= center) { + //向左贴边 + AttachButton.this.animate() + .setInterpolator(new BounceInterpolator()) + .setDuration(500) + .x(0) + .start(); + } else { + //向右贴边 + AttachButton.this.animate() + .setInterpolator(new BounceInterpolator()) + .setDuration(500) + .x(mRootMeasuredWidth - getWidth()) + .start(); + } + } + } + break; + } + } + //是否拦截事件 + return isDrug ? isDrug : super.onTouchEvent(ev); + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/weight/FullyGridLayoutManager.java b/mylibrary/src/main/java/com/dahe/mylibrary/weight/FullyGridLayoutManager.java new file mode 100644 index 0000000..ed6da0e --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/weight/FullyGridLayoutManager.java @@ -0,0 +1,104 @@ +package com.dahe.mylibrary.weight; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +/** + * author:luck + * project:PictureSelector + * package:com.luck.picture.ui + * email:893855882@qq.com + * data:16/12/31 + */ + +public class FullyGridLayoutManager extends GridLayoutManager { + public FullyGridLayoutManager(Context context, int spanCount) { + super(context, spanCount); + } + + public FullyGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) { + super(context, spanCount, orientation, reverseLayout); + } + + private int[] mMeasuredDimension = new int[2]; + + @Override + public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { + final int widthMode = View.MeasureSpec.getMode(widthSpec); + final int heightMode = View.MeasureSpec.getMode(heightSpec); + final int widthSize = View.MeasureSpec.getSize(widthSpec); + final int heightSize = View.MeasureSpec.getSize(heightSpec); + + int width = 0; + int height = 0; + int count = getItemCount(); + int span = getSpanCount(); + for (int i = 0; i < count; i++) { + measureScrapChild(recycler, i, + View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), + View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), + mMeasuredDimension); + + if (getOrientation() == HORIZONTAL) { + if (i % span == 0) { + width = width + mMeasuredDimension[0]; + } + if (i == 0) { + height = mMeasuredDimension[1]; + } + } else { + if (i % span == 0) { + height = height + mMeasuredDimension[1]; + } + if (i == 0) { + width = mMeasuredDimension[0]; + } + } + } + + switch (widthMode) { + case View.MeasureSpec.EXACTLY: + width = widthSize; + case View.MeasureSpec.AT_MOST: + case View.MeasureSpec.UNSPECIFIED: + } + + switch (heightMode) { + case View.MeasureSpec.EXACTLY: + height = heightSize; + case View.MeasureSpec.AT_MOST: + case View.MeasureSpec.UNSPECIFIED: + } + + setMeasuredDimension(width, height); + } + + final RecyclerView.State mState = new RecyclerView.State(); + + private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, + int heightSpec, int[] measuredDimension) { + int itemCount = mState.getItemCount(); + if (position < itemCount) { + try { + View view = recycler.getViewForPosition(0); + if (view != null) { + RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams(); + int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, + getPaddingLeft() + getPaddingRight(), p.width); + int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, + getPaddingTop() + getPaddingBottom(), p.height); + view.measure(childWidthSpec, childHeightSpec); + measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin; + measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin; + recycler.recycleView(view); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/weight/GlideCircleWithBorder.java b/mylibrary/src/main/java/com/dahe/mylibrary/weight/GlideCircleWithBorder.java new file mode 100644 index 0000000..24f7cf3 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/weight/GlideCircleWithBorder.java @@ -0,0 +1,67 @@ +package com.dahe.mylibrary.weight; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapShader; +import android.graphics.Canvas; +import android.graphics.Paint; + +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; +import com.bumptech.glide.load.resource.bitmap.BitmapTransformation; + +import java.security.MessageDigest; + +/** + * 加载圆形头像带白色边框 + */ +public class GlideCircleWithBorder extends BitmapTransformation { + private Paint mBorderPaint; + private float mBorderWidth; + + public GlideCircleWithBorder(Context context, int borderWidth, int borderColor) { + mBorderWidth = Resources.getSystem().getDisplayMetrics().density * borderWidth; + mBorderPaint = new Paint(); + mBorderPaint.setDither(true); + mBorderPaint.setAntiAlias(true); + mBorderPaint.setColor(borderColor); + mBorderPaint.setStyle(Paint.Style.STROKE); + mBorderPaint.setStrokeWidth(mBorderWidth); + } + + protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { + return circleCrop(pool, toTransform); + } + + private Bitmap circleCrop(BitmapPool pool, Bitmap source) { + if (source == null) { + return null; + } + int size = (int) (Math.min(source.getWidth(), source.getHeight()) - (mBorderWidth / 2)); + int x = (source.getWidth() - size) / 2; + int y = (source.getHeight() - size) / 2; + Bitmap squared = Bitmap.createBitmap(source, x, y, size, size); + Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888); + if (result == null) { + result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); + } + //创建画笔 画布 手动描绘边框 + Canvas canvas = new Canvas(result); + Paint paint = new Paint(); + paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP)); + paint.setAntiAlias(true); + float r = size / 2f; + canvas.drawCircle(r, r, r, paint); + if (mBorderPaint != null) { + float borderRadius = r - mBorderWidth / 2; + canvas.drawCircle(r, r, borderRadius, mBorderPaint); + } + return result; + } + + @Override + public void updateDiskCacheKey(MessageDigest messageDigest) { + + } + +} \ No newline at end of file diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/weight/GlideEngine.java b/mylibrary/src/main/java/com/dahe/mylibrary/weight/GlideEngine.java new file mode 100644 index 0000000..e531d35 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/weight/GlideEngine.java @@ -0,0 +1,233 @@ +package com.dahe.mylibrary.weight; + + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.PointF; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.bumptech.glide.request.target.ImageViewTarget; +import com.dahe.mylibrary.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.tools.MediaUtils; +import com.luck.picture.lib.widget.longimage.ImageSource; +import com.luck.picture.lib.widget.longimage.ImageViewState; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @author:luck + * @date:2019-11-13 17:02 + * @describe:Glide加载引擎 + */ +public class GlideEngine implements ImageEngine { + + /** + * 加载图片 + * + * @param context + * @param url + * @param imageView + */ + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .into(imageView); + } + + + /** + * 加载网络图片适配长图方案 + * # 注意:此方法只有加载网络图片才会回调 + * + * @param context + * @param url + * @param imageView + * @param longImageView + * @param callback 网络图片加载回调监听 {link after version 2.5.1 Please use the #OnImageCompleteCallback#} + */ + @Override + public void loadImage(@NonNull Context context, @NonNull String url, + @NonNull final ImageView imageView, + final SubsamplingScaleImageView longImageView, final OnImageCompleteCallback callback) { + Glide.with(context) + .asBitmap() + .load(url) + .into(new ImageViewTarget(imageView) { + @Override + public void onLoadStarted(@Nullable Drawable placeholder) { + super.onLoadStarted(placeholder); + if (callback != null) { + callback.onShowLoading(); + } + } + + @Override + public void onLoadFailed(@Nullable Drawable errorDrawable) { + super.onLoadFailed(errorDrawable); + if (callback != null) { + callback.onHideLoading(); + } + } + + @Override + protected void setResource(@Nullable Bitmap resource) { + if (callback != null) { + callback.onHideLoading(); + } + if (resource != null) { + boolean eqLongImage = MediaUtils.isLongImg(resource.getWidth(), + resource.getHeight()); + longImageView.setVisibility(eqLongImage ? View.VISIBLE : View.GONE); + imageView.setVisibility(eqLongImage ? View.GONE : View.VISIBLE); + if (eqLongImage) { + // 加载长图 + longImageView.setQuickScaleEnabled(true); + longImageView.setZoomEnabled(true); + longImageView.setDoubleTapZoomDuration(100); + longImageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_CROP); + longImageView.setDoubleTapZoomDpi(SubsamplingScaleImageView.ZOOM_FOCUS_CENTER); + longImageView.setImage(ImageSource.bitmap(resource), + new ImageViewState(0, new PointF(0, 0), 0)); + } else { + // 普通图片 + imageView.setImageBitmap(resource); + } + } + } + }); + } + + /** + * 加载网络图片适配长图方案 + * # 注意:此方法只有加载网络图片才会回调 + * + * @param context + * @param url + * @param imageView + * @param longImageView + * @ 已废弃 + */ + @Override + public void loadImage(@NonNull Context context, @NonNull String url, + @NonNull final ImageView imageView, + final SubsamplingScaleImageView longImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .into(new ImageViewTarget(imageView) { + @Override + protected void setResource(@Nullable Bitmap resource) { + if (resource != null) { + boolean eqLongImage = MediaUtils.isLongImg(resource.getWidth(), + resource.getHeight()); + longImageView.setVisibility(eqLongImage ? View.VISIBLE : View.GONE); + imageView.setVisibility(eqLongImage ? View.GONE : View.VISIBLE); + if (eqLongImage) { + // 加载长图 + longImageView.setQuickScaleEnabled(true); + longImageView.setZoomEnabled(true); + longImageView.setDoubleTapZoomDuration(100); + longImageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_CROP); + longImageView.setDoubleTapZoomDpi(SubsamplingScaleImageView.ZOOM_FOCUS_CENTER); + longImageView.setImage(ImageSource.bitmap(resource), + new ImageViewState(0, new PointF(0, 0), 0)); + } else { + // 普通图片 + imageView.setImageBitmap(resource); + } + } + } + }); + } + + /** + * 加载相册目录 + * + * @param context 上下文 + * @param url 图片路径 + * @param imageView 承载图片ImageView + */ + @Override + public void loadFolderImage(@NonNull final Context context, @NonNull String url, @NonNull final ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .centerCrop() + .sizeMultiplier(0.5f) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + + /** + * 加载gif + * + * @param context 上下文 + * @param url 图片路径 + * @param imageView 承载图片ImageView + */ + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, + @NonNull ImageView imageView) { + Glide.with(context) + .asGif() + .load(url) + .into(imageView); + } + + /** + * 加载图片列表图片 + * + * @param context 上下文 + * @param url 图片路径 + * @param imageView 承载图片ImageView + */ + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .override(200, 200) + .centerCrop() + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } + + + private GlideEngine() { + } + + private static GlideEngine instance; + + public static GlideEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideEngine.class) { + if (null == instance) { + instance = new GlideEngine(); + } + } + } + return instance; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/weight/GridSectionAverageGapItemDecoration.java b/mylibrary/src/main/java/com/dahe/mylibrary/weight/GridSectionAverageGapItemDecoration.java new file mode 100644 index 0000000..6fa5c4b --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/weight/GridSectionAverageGapItemDecoration.java @@ -0,0 +1,231 @@ +package com.dahe.mylibrary.weight; + +import android.graphics.Rect; +import android.os.Build; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import android.view.View; + +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.chad.library.adapter.base.BaseSectionQuickAdapter; +import com.chad.library.adapter.base.entity.SectionEntity; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; + +import java.util.ArrayList; +import java.util.List; + +/** + * 应用于RecyclerView的GridLayoutManager,水平方向上固定间距大小,从而使条目宽度自适应。
+ * 配合Brvah的Section使用,不对Head生效,仅对每个Head的子Grid列表生效
+ * Section Grid中Item的宽度应设为MATCH_PARAENT + * + * @author : renpeng + * @since : 2018/9/29 + */ +public class GridSectionAverageGapItemDecoration extends RecyclerView.ItemDecoration { + + private class Section { + public int startPos = 0; + public int endPos = 0; + + public int getCount() { + return endPos - startPos + 1; + } + + public boolean contains(int pos) { + return pos >= startPos && pos <= endPos; + } + + @Override + public String toString() { + return "Section{" + + "startPos=" + startPos + + ", endPos=" + endPos + + '}'; + } + } + + private float gapHorizontalDp; + private float gapVerticalDp; + private float sectionEdgeHPaddingDp; + private float sectionEdgeVPaddingDp; + private int gapHSizePx = -1; + private int gapVSizePx = -1; + private int sectionEdgeHPaddingPx; + private int eachItemHPaddingPx; //每个条目应该在水平方向上加的padding 总大小,即=paddingLeft+paddingRight + private int sectionEdgeVPaddingPx; + private List
mSectionList = new ArrayList<>(); + private BaseSectionQuickAdapter mAdapter; + private RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() { + @Override + public void onChanged() { + markSections(); + } + + @Override + public void onItemRangeChanged(int positionStart, int itemCount) { + markSections(); + } + + @Override + public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) { + markSections(); + } + + @Override + public void onItemRangeInserted(int positionStart, int itemCount) { + markSections(); + } + + @Override + public void onItemRangeRemoved(int positionStart, int itemCount) { + markSections(); + } + + @Override + public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { + markSections(); + } + }; + + + /** + * @param gapHorizontalDp item之间的水平间距 + * @param gapVerticalDp item之间的垂直间距 + * @param sectionEdgeHPaddingDp section左右两端的padding大小 + * @param sectionEdgeVPaddingDp section上下两端的padding大小 + */ + public GridSectionAverageGapItemDecoration(float gapHorizontalDp, float gapVerticalDp, float sectionEdgeHPaddingDp, float sectionEdgeVPaddingDp) { + this.gapHorizontalDp = gapHorizontalDp; + this.gapVerticalDp = gapVerticalDp; + this.sectionEdgeHPaddingDp = sectionEdgeHPaddingDp; + this.sectionEdgeVPaddingDp = sectionEdgeVPaddingDp; + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + if (parent.getLayoutManager() instanceof GridLayoutManager && parent.getAdapter() instanceof BaseSectionQuickAdapter) { + GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager(); + BaseSectionQuickAdapter adapter = (BaseSectionQuickAdapter) parent.getAdapter(); + if (mAdapter != adapter) { + setUpWithAdapter(adapter); + } + int spanCount = layoutManager.getSpanCount(); + int position = parent.getChildAdapterPosition(view) - mAdapter.getHeaderLayoutCount(); + SectionEntity entity = adapter.getItem(position); + + if (entity == null || entity.isHeader()) { + //不处理header + outRect.set(0, 0, 0, 0); +// Log.w("GridAverageGapItem", "pos=" + position + "," + outRect.toShortString()); + return; + } + + Section section = findSectionLastItemPos(position); + + if (gapHSizePx < 0 || gapVSizePx < 0) { + transformGapDefinition(parent, spanCount); + } + outRect.top = gapVSizePx; + outRect.bottom = 0; + + //下面的visualPos为单个Section内的视觉Pos + int visualPos = position + 1 - section.startPos; + if (visualPos % spanCount == 1) { + //第一列 + outRect.left = sectionEdgeHPaddingPx; + outRect.right = eachItemHPaddingPx - sectionEdgeHPaddingPx; + } else if (visualPos % spanCount == 0) { + //最后一列 + outRect.left = eachItemHPaddingPx - sectionEdgeHPaddingPx; + outRect.right = sectionEdgeHPaddingPx; + } else { + outRect.left = gapHSizePx - (eachItemHPaddingPx - sectionEdgeHPaddingPx); + outRect.right = eachItemHPaddingPx - outRect.left; + } + + if (visualPos - spanCount <= 0) { + //第一行 + outRect.top = sectionEdgeVPaddingPx; + } + + if (isLastRow(visualPos, spanCount, section.getCount())) { + //最后一行 + outRect.bottom = sectionEdgeVPaddingPx; +// Log.w("GridAverageGapItem", "last row pos=" + position); + } +// Log.w("GridAverageGapItem", "pos=" + position + ",vPos=" + visualPos + "," + outRect.toShortString()); + } else { + super.getItemOffsets(outRect, view, parent, state); + } + } + + private void setUpWithAdapter(BaseSectionQuickAdapter adapter) { + if (mAdapter != null) { + mAdapter.unregisterAdapterDataObserver(mDataObserver); + } + mAdapter = adapter; + mAdapter.registerAdapterDataObserver(mDataObserver); + markSections(); + } + + private void markSections() { + if (mAdapter != null) { + BaseSectionQuickAdapter adapter = mAdapter; + mSectionList.clear(); + SectionEntity sectionEntity = null; + Section section = new Section(); + for (int i = 0, size = adapter.getItemCount(); i < size; i++) { + sectionEntity = adapter.getItem(i); + if (sectionEntity != null && sectionEntity.isHeader()) { + //找到新Section起点 + if (section != null && i != 0) { + //已经有待添加的section + section.endPos = i - 1; + mSectionList.add(section); + } + section = new Section(); + section.startPos = i + 1; + } else { + section.endPos = i; + } + } + //处理末尾情况 + if (!mSectionList.contains(section)) { + mSectionList.add(section); + } + +// Log.w("GridAverageGapItem", "section list=" + mSectionList); + } + } + + private void transformGapDefinition(RecyclerView parent, int spanCount) { + DisplayMetrics displayMetrics = new DisplayMetrics(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + parent.getDisplay().getMetrics(displayMetrics); + } + gapHSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapHorizontalDp, displayMetrics); + gapVSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapVerticalDp, displayMetrics); + sectionEdgeHPaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sectionEdgeHPaddingDp, displayMetrics); + sectionEdgeVPaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sectionEdgeVPaddingDp, displayMetrics); + eachItemHPaddingPx = (sectionEdgeHPaddingPx * 2 + gapHSizePx * (spanCount - 1)) / spanCount; + } + + private Section findSectionLastItemPos(int curPos) { + for (Section section : mSectionList) { + if (section.contains(curPos)) { + return section; + } + } + return null; + } + + private boolean isLastRow(int visualPos, int spanCount, int sectionItemCount) { + int lastRowCount = sectionItemCount % spanCount; + lastRowCount = lastRowCount == 0 ? spanCount : lastRowCount; + return visualPos > sectionItemCount - lastRowCount; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/weight/MovedImageButton.java b/mylibrary/src/main/java/com/dahe/mylibrary/weight/MovedImageButton.java new file mode 100644 index 0000000..841f073 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/weight/MovedImageButton.java @@ -0,0 +1,93 @@ +package com.dahe.mylibrary.weight; + +import android.animation.ObjectAnimator; +import android.annotation.SuppressLint; +import android.content.Context; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.view.MotionEvent; +import android.view.animation.OvershootInterpolator; +import android.widget.ImageButton; + +import com.dahe.mylibrary.utils.BaseUtils; + +public class MovedImageButton extends androidx.appcompat.widget.AppCompatImageButton { + private int lastX; + private int lastY; + private float screenWidth; + + public MovedImageButton(Context context) { + super(context); + } + + public MovedImageButton(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public MovedImageButton(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + DisplayMetrics dm = getResources().getDisplayMetrics(); + screenWidth = dm.widthPixels; + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouchEvent(MotionEvent event) { + int x = (int) event.getX(); + int y = (int) event.getY(); + switch (event.getAction()){ + case MotionEvent.ACTION_DOWN: + lastX = x; + lastY = y; + break; + case MotionEvent.ACTION_MOVE: + int offsetX = x-lastX; + int offsetY = y-lastY; + //第一种方法 +// layout(getLeft()+offsetX, +// getTop()+offsetY, +// getRight()+offsetX, +// getBottom()+offsetY); + //第二种方法 + offsetLeftAndRight(offsetX); + offsetTopAndBottom(offsetY); + break; + case MotionEvent.ACTION_UP: + adsorbAnim(event.getRawX(), event.getRawY()); + break; + } + return super.onTouchEvent(event); + } + + private void adsorbAnim(float rawX, float rawY){ + //靠顶吸附 +// if (rawY <= BaseUtils.dip2px(getContext(),200)){//注意rawY包含了标题栏的高 +// animate().setDuration(400) +// .setInterpolator(new OvershootInterpolator()) +// .yBy(-getY()-getHeight()/2.0f) +// .start(); +// }else + + if (rawX >= screenWidth/2){//靠右吸附 + animate().setDuration(400) + .setInterpolator(new OvershootInterpolator()) + .xBy(screenWidth - getX() - getWidth()) + .start(); + }else {//靠左吸附 + ObjectAnimator animator = ObjectAnimator.ofFloat(this, "x", getX(), 0); + animator.setInterpolator(new OvershootInterpolator()); + animator.setDuration(400); + animator.start(); + } + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/weight/MySlideBar.java b/mylibrary/src/main/java/com/dahe/mylibrary/weight/MySlideBar.java new file mode 100644 index 0000000..7bd8b59 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/weight/MySlideBar.java @@ -0,0 +1,191 @@ +package com.dahe.mylibrary.weight; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import androidx.annotation.Nullable; + +import com.dahe.mylibrary.R; +import com.dahe.mylibrary.utils.ToastUtils; + +public class MySlideBar extends RelativeLayout implements View.OnClickListener { + + private boolean canSelect; + private TextView tvT1; + private TextView tvT2; + private TextView tvT3; + private TextView tvT4; + private TextView tvC1; + private TextView tvC2; + private TextView tvC3; + private TextView tvC4; + private View view1; + private View view2; + + public MySlideBar(Context context) { + this(context, null); + } + + public MySlideBar(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public MySlideBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + this(context, attrs, 0, 0); + } + + public MySlideBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(context, attrs); + + + } + + private void init(Context context, AttributeSet attrs) { + View inflate = View.inflate(context, R.layout.view_slide_bar, this); + tvT1 = (TextView) findViewById(R.id.tv_title1); + tvT2 = (TextView) findViewById(R.id.tv_title2); + tvT3 = (TextView) findViewById(R.id.tv_title3); + tvT4 = (TextView) findViewById(R.id.tv_title4); + tvC1 = (TextView) findViewById(R.id.tv_conten1); + tvC2 = (TextView) findViewById(R.id.tv_content2); + tvC3 = (TextView) findViewById(R.id.tv_content3); + tvC4 = (TextView) findViewById(R.id.tv_content4); + view1 = (View) findViewById(R.id.view1); + view2 = (View) findViewById(R.id.view2); + LinearLayout ll1 = (LinearLayout) findViewById(R.id.ll1); + LinearLayout ll2 = (LinearLayout) findViewById(R.id.ll2); + LinearLayout ll3 = (LinearLayout) findViewById(R.id.ll3); + LinearLayout ll4 = (LinearLayout) findViewById(R.id.ll4); + ll1.setOnClickListener(this); + ll2.setOnClickListener(this); + ll3.setOnClickListener(this); + ll4.setOnClickListener(this); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MySlideBar); + int integer = a.getInteger(R.styleable.MySlideBar_proress, -1); + canSelect = a.getBoolean(R.styleable.MySlideBar_canSelect, false); + changeProress(integer,true); + + a.recycle(); + } + + @Override + public void onClick(View v) { + if (canSelect) { + int id = v.getId(); + if (id == R.id.ll1) { + changeProress(0,canSelect); + } else if (id == R.id.ll2) { + changeProress(1,canSelect); + } else if (id == R.id.ll3) { + changeProress(2,canSelect); + } else if (id == R.id.ll4) { + changeProress(3,canSelect); + } + } + + } + + public void setProress(int proress){ + changeProress(proress,canSelect); + } + + private void changeProress(int integer,boolean canSelect){ + if (listener!=null&&canSelect){ + listener.onChange(integer); + } + if (0 == integer) { + tvT1.setBackgroundResource(R.drawable.select_slide_title); + tvT2.setBackgroundResource(R.drawable.select_slide_title); + tvT3.setBackgroundResource(R.drawable.select_slide_title); + tvT4.setBackgroundResource(R.drawable.select_slide_title); + tvT1.setText("1"); + tvT2.setText("2"); + tvT3.setText("3"); + tvT4.setText("4"); + tvT1.setSelected(true); + tvT2.setSelected(false); + tvT3.setSelected(false); + tvT4.setSelected(false); + + view1.setBackgroundResource(R.color.color_d5); + view2.setBackgroundResource(R.color.color_d5); + + tvC1.setTextColor(getResources().getColor(R.color.mine_top_bg)); + tvC2.setTextColor(getResources().getColor(R.color.color_9)); + tvC3.setTextColor(getResources().getColor(R.color.color_9)); + tvC4.setTextColor(getResources().getColor(R.color.color_9)); + } else if (1 == integer) { + tvT1.setBackgroundResource(R.drawable.ok); + tvT2.setBackgroundResource(R.drawable.select_slide_title); + tvT3.setBackgroundResource(R.drawable.select_slide_title); + tvT4.setBackgroundResource(R.drawable.select_slide_title); + tvT1.setText(""); + tvT2.setText("2"); + tvT3.setText("3"); + tvT4.setText("4"); + tvT2.setSelected(true); + tvT3.setSelected(false); + tvT4.setSelected(false); + + view1.setBackgroundResource(R.color.mine_top_bg); + view2.setBackgroundResource(R.color.color_d5); + + tvC1.setTextColor(getResources().getColor(R.color.black)); + tvC2.setTextColor(getResources().getColor(R.color.mine_top_bg)); + tvC3.setTextColor(getResources().getColor(R.color.color_9)); + tvC4.setTextColor(getResources().getColor(R.color.color_9)); + } else if (2 == integer) { + tvT1.setBackgroundResource(R.drawable.ok); + tvT2.setBackgroundResource(R.drawable.ok); + tvT3.setBackgroundResource(R.drawable.select_slide_title); + tvT4.setBackgroundResource(R.drawable.select_slide_title); + tvT1.setText(""); + tvT2.setText(""); + tvT3.setText("3"); + tvT4.setText("4"); + tvT3.setSelected(true); + tvT4.setSelected(false); + + view1.setBackgroundResource(R.color.mine_top_bg); + view2.setBackgroundResource(R.color.mine_top_bg); + + tvC1.setTextColor(getResources().getColor(R.color.black)); + tvC2.setTextColor(getResources().getColor(R.color.black)); + tvC3.setTextColor(getResources().getColor(R.color.mine_top_bg)); + tvC4.setTextColor(getResources().getColor(R.color.color_9)); + } else if (3 == integer) { + tvT1.setBackgroundResource(R.drawable.ok); + tvT2.setBackgroundResource(R.drawable.ok); + tvT3.setBackgroundResource(R.drawable.ok); + tvT4.setBackgroundResource(R.drawable.select_slide_title); + tvT1.setText(""); + tvT2.setText(""); + tvT3.setText(""); + tvT4.setText("4"); + tvT4.setSelected(true); + + tvC1.setTextColor(getResources().getColor(R.color.black)); + tvC2.setTextColor(getResources().getColor(R.color.black)); + tvC3.setTextColor(getResources().getColor(R.color.black)); + tvC4.setTextColor(getResources().getColor(R.color.mine_top_bg)); + } + } + + + public interface OnChangeListener{ + void onChange(int progress); + } + + private OnChangeListener listener; + public void setOnChangeListener(OnChangeListener listener){ + this.listener = listener; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/weight/SideBar.java b/mylibrary/src/main/java/com/dahe/mylibrary/weight/SideBar.java new file mode 100644 index 0000000..1b1e471 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/weight/SideBar.java @@ -0,0 +1,130 @@ +package com.dahe.mylibrary.weight; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Typeface; +import android.graphics.drawable.ColorDrawable; +import android.os.Vibrator; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.widget.TextView; + +import com.dahe.mylibrary.R; + +public class SideBar extends View { + // 触摸事件 + private OnTouchingLetterChangedListener onTouchingLetterChangedListener; + public static String[] b = { "A", "B", "C", "D", "E", "F", "G", "H", "I", + "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", + "W", "X", "Y", "Z", "#" }; + private int choose = -1; + private Paint paint = new Paint(); + + private TextView mTextDialog; + + /** + * 为SideBar设置显示字母的TextView + * @param textDialog + */ + public void setTextView(TextView textDialog) { + this.mTextDialog = textDialog; + } + + + public SideBar(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public SideBar(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public SideBar(Context context) { + super(context); + } + + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + int height = getHeight(); + int width = getWidth(); + int singleHeight = height / b.length;// 获取每一个字母的高度 + + for (int i = 0; i < b.length; i++) { + paint.setColor(Color.rgb(33, 65, 98)); + // paint.setColor(Color.WHITE); + paint.setTypeface(Typeface.DEFAULT_BOLD); + paint.setAntiAlias(true); + paint.setTextSize(20); + if (i == choose) {// 选中的状态 + paint.setColor(Color.parseColor("#999999")); + paint.setFakeBoldText(true); + } + // x坐标等于中间-字符串宽度的一半 + float xPos = width / 2 - paint.measureText(b[i]) / 2; + float yPos = singleHeight * i + singleHeight; + canvas.drawText(b[i], xPos, yPos, paint); + paint.reset(); + } + + } + + @Override + public boolean dispatchTouchEvent(MotionEvent event) { + final int action = event.getAction(); + final float y = event.getY(); + final int oldChoose = choose; + final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener; + final int c = (int) (y / getHeight() * b.length);// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数 + + switch (action) { + case MotionEvent.ACTION_UP: + setBackground(new ColorDrawable(0x00000000)); + choose = -1;// + invalidate(); + if (mTextDialog != null) { + mTextDialog.setVisibility(View.INVISIBLE); + } + break; + + default: +// setBackgroundResource(R.drawable.sidebar_background); + if (oldChoose != c) { + if (c >= 0 && c < b.length) { + if (listener != null) { + listener.onTouchingLetterChanged(b[c]); + } + if (mTextDialog != null) { + mTextDialog.setText(b[c]); + mTextDialog.setVisibility(View.VISIBLE); + } + + choose = c; + invalidate(); + } + } + + break; + } + return true; + } + + /** + * 触摸事件 + * @param onTouchingLetterChangedListener + */ + public void setOnTouchingLetterChangedListener( + OnTouchingLetterChangedListener onTouchingLetterChangedListener) { + this.onTouchingLetterChangedListener = onTouchingLetterChangedListener; + } + + /** + * 回调接口 + */ + public interface OnTouchingLetterChangedListener { + void onTouchingLetterChanged(String s); + } + +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/weight/SwitchView.java b/mylibrary/src/main/java/com/dahe/mylibrary/weight/SwitchView.java new file mode 100644 index 0000000..93fbb50 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/weight/SwitchView.java @@ -0,0 +1,508 @@ +package com.dahe.mylibrary.weight; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.RadialGradient; +import android.graphics.RectF; +import android.graphics.Shader; +import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.MotionEvent; +import android.view.View; +import android.view.animation.AccelerateInterpolator; + +import com.dahe.mylibrary.R; + + +/** + * hei hei hei + */ +public class SwitchView extends View { + + private static final int STATE_SWITCH_ON = 4; + private static final int STATE_SWITCH_ON2 = 3; + private static final int STATE_SWITCH_OFF2 = 2; + private static final int STATE_SWITCH_OFF = 1; + + private final AccelerateInterpolator interpolator = new AccelerateInterpolator(2); + private final Paint paint = new Paint(); + private final Path sPath = new Path(); + private final Path bPath = new Path(); + private final RectF bRectF = new RectF(); + private float sAnim, bAnim; + private RadialGradient shadowGradient; + + protected float ratioAspect = 0.68f; // (0,1] + protected float animationSpeed = 0.1f; // (0,1] + + private int state; + private int lastState; + private boolean isCanVisibleDrawing = false; + private OnClickListener mOnClickListener; + protected int colorPrimary; + protected int colorPrimaryDark; + protected int colorOff; + protected int colorOffDark; + protected int colorShadow; + protected boolean hasShadow; + protected boolean isOpened; + protected boolean canEnable; + + private float sRight; + private float sCenterX, sCenterY; + private float sScale; + + private float bOffset; + private float bRadius, bStrokeWidth; + private float bWidth; + private float bLeft; + private float bRight; + private float bOnLeftX, bOn2LeftX, bOff2LeftX, bOffLeftX; + + private float shadowReservedHeight; + + public SwitchView(Context context) { + this(context, null); + } + + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public SwitchView(Context context, AttributeSet attrs) { + super(context, attrs); + setLayerType(LAYER_TYPE_SOFTWARE, null); + + final int DEFAULT_COLOR_PRIMARY = 0xFF4BD763; + final int DEFAULT_COLOR_PRIMARY_DARK = 0xFF3AC652; + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SwitchView); + colorPrimary = a.getColor(R.styleable.SwitchView_primaryColor, DEFAULT_COLOR_PRIMARY); + colorPrimaryDark = a.getColor(R.styleable.SwitchView_primaryColorDark, DEFAULT_COLOR_PRIMARY_DARK); + colorOff = a.getColor(R.styleable.SwitchView_offColor, 0xFFE3E3E3); + colorOffDark = a.getColor(R.styleable.SwitchView_offColorDark, 0xFFBFBFBF); + colorShadow = a.getColor(R.styleable.SwitchView_shadowColor, 0xFF333333); + ratioAspect = a.getFloat(R.styleable.SwitchView_ratioAspect, 0.68f); + hasShadow = a.getBoolean(R.styleable.SwitchView_hasShadow, true); + isOpened = a.getBoolean(R.styleable.SwitchView_isOpened, false); + canEnable = a.getBoolean(R.styleable.SwitchView_canEnable, true); + state = isOpened ? STATE_SWITCH_ON : STATE_SWITCH_OFF; + lastState = state; + a.recycle(); + + if (colorPrimary == DEFAULT_COLOR_PRIMARY && colorPrimaryDark == DEFAULT_COLOR_PRIMARY_DARK) { + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + TypedValue primaryColorTypedValue = new TypedValue(); + context.getTheme().resolveAttribute(android.R.attr.colorPrimary, primaryColorTypedValue, true); + if (primaryColorTypedValue.data > 0) colorPrimary = primaryColorTypedValue.data; + TypedValue primaryColorDarkTypedValue = new TypedValue(); + context.getTheme().resolveAttribute(android.R.attr.colorPrimaryDark, primaryColorDarkTypedValue, true); + if (primaryColorDarkTypedValue.data > 0) + colorPrimaryDark = primaryColorDarkTypedValue.data; + } + } catch (Exception ignore) { + } + } + } + + public void setColor(int newColorPrimary, int newColorPrimaryDark) { + setColor(newColorPrimary, newColorPrimaryDark, colorOff, colorOffDark); + } + + public void setColor(int newColorPrimary, int newColorPrimaryDark, int newColorOff, int newColorOffDark) { + setColor(newColorPrimary, newColorPrimaryDark, newColorOff, newColorOffDark, colorShadow); + } + + public void setColor(int newColorPrimary, int newColorPrimaryDark, int newColorOff, int newColorOffDark, int newColorShadow) { + colorPrimary = newColorPrimary; + colorPrimaryDark = newColorPrimaryDark; + colorOff = newColorOff; + colorOffDark = newColorOffDark; + colorShadow = newColorShadow; + invalidate(); + } + + public void setCanEnable(boolean canEnable){ + this.canEnable = canEnable; + invalidate(); + } + + public void setShadow(boolean shadow) { + hasShadow = shadow; + invalidate(); + } + + public boolean isOpened() { + return isOpened; + } + + public void setOpened(boolean isOpened) { + int wishState = isOpened ? STATE_SWITCH_ON : STATE_SWITCH_OFF; + if (wishState == state) { + return; + } + refreshState(wishState); + } + + public void toggleSwitch(boolean isOpened) { + int wishState = isOpened ? STATE_SWITCH_ON : STATE_SWITCH_OFF; + if (wishState == state) { + return; + } + if ((wishState == STATE_SWITCH_ON && (state == STATE_SWITCH_OFF || state == STATE_SWITCH_OFF2)) + || (wishState == STATE_SWITCH_OFF && (state == STATE_SWITCH_ON || state == STATE_SWITCH_ON2))) { + sAnim = 1; + } + bAnim = 1; + refreshState(wishState); + } + + private void refreshState(int newState) { + if (!isOpened && newState == STATE_SWITCH_ON) { + isOpened = true; + } else if (isOpened && newState == STATE_SWITCH_OFF) { + isOpened = false; + } + lastState = state; + state = newState; + postInvalidate(); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + int resultWidth; + if (widthMode == MeasureSpec.EXACTLY) { + resultWidth = widthSize; + } else { + resultWidth = (int) (56 * getResources().getDisplayMetrics().density + 0.5f) + + getPaddingLeft() + getPaddingRight(); + if (widthMode == MeasureSpec.AT_MOST) { + resultWidth = Math.min(resultWidth, widthSize); + } + } + + int heightSize = MeasureSpec.getSize(heightMeasureSpec); + int heightMode = MeasureSpec.getMode(heightMeasureSpec); + int resultHeight; + if (heightMode == MeasureSpec.EXACTLY) { + resultHeight = heightSize; + } else { + resultHeight = (int) (resultWidth * ratioAspect) + getPaddingTop() + getPaddingBottom(); + if (heightMode == MeasureSpec.AT_MOST) { + resultHeight = Math.min(resultHeight, heightSize); + } + } + setMeasuredDimension(resultWidth, resultHeight); + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + + isCanVisibleDrawing = w > getPaddingLeft() + getPaddingRight() && h > getPaddingTop() + getPaddingBottom(); + + if (isCanVisibleDrawing) { + int actuallyDrawingAreaWidth = w - getPaddingLeft() - getPaddingRight(); + int actuallyDrawingAreaHeight = h - getPaddingTop() - getPaddingBottom(); + + int actuallyDrawingAreaLeft; + int actuallyDrawingAreaRight; + int actuallyDrawingAreaTop; + int actuallyDrawingAreaBottom; + if (actuallyDrawingAreaWidth * ratioAspect < actuallyDrawingAreaHeight) { + actuallyDrawingAreaLeft = getPaddingLeft(); + actuallyDrawingAreaRight = w - getPaddingRight(); + int heightExtraSize = (int) (actuallyDrawingAreaHeight - actuallyDrawingAreaWidth * ratioAspect); + actuallyDrawingAreaTop = getPaddingTop() + heightExtraSize / 2; + actuallyDrawingAreaBottom = getHeight() - getPaddingBottom() - heightExtraSize / 2; + } else { + int widthExtraSize = (int) (actuallyDrawingAreaWidth - actuallyDrawingAreaHeight / ratioAspect); + actuallyDrawingAreaLeft = getPaddingLeft() + widthExtraSize / 2; + actuallyDrawingAreaRight = getWidth() - getPaddingRight() - widthExtraSize / 2; + actuallyDrawingAreaTop = getPaddingTop(); + actuallyDrawingAreaBottom = getHeight() - getPaddingBottom(); + } + + shadowReservedHeight = (int) ((actuallyDrawingAreaBottom - actuallyDrawingAreaTop) * 0.07f); + float sLeft = actuallyDrawingAreaLeft; + float sTop = actuallyDrawingAreaTop + shadowReservedHeight; + sRight = actuallyDrawingAreaRight; + float sBottom = actuallyDrawingAreaBottom - shadowReservedHeight; + + float sHeight = sBottom - sTop; + sCenterX = (sRight + sLeft) / 2; + sCenterY = (sBottom + sTop) / 2; + + bLeft = sLeft; + bWidth = sBottom - sTop; + bRight = sLeft + bWidth; + final float halfHeightOfS = bWidth / 2; // OfB + bRadius = halfHeightOfS * 0.95f; + bOffset = bRadius * 0.2f; // offset of switching + bStrokeWidth = (halfHeightOfS - bRadius) * 2; + bOnLeftX = sRight - bWidth; + bOn2LeftX = bOnLeftX - bOffset; + bOffLeftX = sLeft; + bOff2LeftX = bOffLeftX + bOffset; + sScale = 1 - bStrokeWidth / sHeight; + + sPath.reset(); + RectF sRectF = new RectF(); + sRectF.top = sTop; + sRectF.bottom = sBottom; + sRectF.left = sLeft; + sRectF.right = sLeft + sHeight; + sPath.arcTo(sRectF, 90, 180); + sRectF.left = sRight - sHeight; + sRectF.right = sRight; + sPath.arcTo(sRectF, 270, 180); + sPath.close(); + + bRectF.left = bLeft; + bRectF.right = bRight; + bRectF.top = sTop + bStrokeWidth / 2; // bTop = sTop + bRectF.bottom = sBottom - bStrokeWidth / 2; // bBottom = sBottom + float bCenterX = (bRight + bLeft) / 2; + float bCenterY = (sBottom + sTop) / 2; + + int red = colorShadow >> 16 & 0xFF; + int green = colorShadow >> 8 & 0xFF; + int blue = colorShadow & 0xFF; + shadowGradient = new RadialGradient(bCenterX, bCenterY, bRadius, Color.argb(200, red, green, blue), + Color.argb(25, red, green, blue), Shader.TileMode.CLAMP); + } + } + + private void calcBPath(float percent) { + bPath.reset(); + bRectF.left = bLeft + bStrokeWidth / 2; + bRectF.right = bRight - bStrokeWidth / 2; + bPath.arcTo(bRectF, 90, 180); + bRectF.left = bLeft + percent * bOffset + bStrokeWidth / 2; + bRectF.right = bRight + percent * bOffset - bStrokeWidth / 2; + bPath.arcTo(bRectF, 270, 180); + bPath.close(); + } + + private float calcBTranslate(float percent) { + float result = 0; + switch (state - lastState) { + case 1: + if (state == STATE_SWITCH_OFF2) { + result = bOffLeftX; // off -> off2 + } else if (state == STATE_SWITCH_ON) { + result = bOnLeftX - (bOnLeftX - bOn2LeftX) * percent; // on2 -> on + } + break; + case 2: + if (state == STATE_SWITCH_ON) { + result = bOnLeftX - (bOnLeftX - bOffLeftX) * percent; // off2 -> on + } else if (state == STATE_SWITCH_ON2) { + result = bOn2LeftX - (bOn2LeftX - bOffLeftX) * percent; // off -> on2 + } + break; + case 3: + result = bOnLeftX - (bOnLeftX - bOffLeftX) * percent; // off -> on + break; + case -1: + if (state == STATE_SWITCH_ON2) { + result = bOn2LeftX + (bOnLeftX - bOn2LeftX) * percent; // on -> on2 + } else if (state == STATE_SWITCH_OFF) { + result = bOffLeftX; // off2 -> off + } + break; + case -2: + if (state == STATE_SWITCH_OFF) { + result = bOffLeftX + (bOn2LeftX - bOffLeftX) * percent; // on2 -> off + } else if (state == STATE_SWITCH_OFF2) { + result = bOff2LeftX + (bOnLeftX - bOff2LeftX) * percent; // on -> off2 + } + break; + case -3: + result = bOffLeftX + (bOnLeftX - bOffLeftX) * percent; // on -> off + break; + default: // init + case 0: + if (state == STATE_SWITCH_OFF) { + result = bOffLeftX; // off -> off + } else if (state == STATE_SWITCH_ON) { + result = bOnLeftX; // on -> on + } + break; + } + return result - bOffLeftX; + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + if (!isCanVisibleDrawing) return; + + paint.setAntiAlias(true); + final boolean isOn = (state == STATE_SWITCH_ON || state == STATE_SWITCH_ON2); + // Draw background + paint.setStyle(Paint.Style.FILL); + paint.setColor(isOn ? colorPrimary : colorOff); + canvas.drawPath(sPath, paint); + + sAnim = sAnim - animationSpeed > 0 ? sAnim - animationSpeed : 0; + bAnim = bAnim - animationSpeed > 0 ? bAnim - animationSpeed : 0; + + final float dsAnim = interpolator.getInterpolation(sAnim); + final float dbAnim = interpolator.getInterpolation(bAnim); + // Draw background animation + final float scale = sScale * (isOn ? dsAnim : 1 - dsAnim); + final float scaleOffset = (sRight - sCenterX - bRadius) * (isOn ? 1 - dsAnim : dsAnim); + canvas.save(); + canvas.scale(scale, scale, sCenterX + scaleOffset, sCenterY); + paint.setColor(0xFFFFFFFF); + canvas.drawPath(sPath, paint); + canvas.restore(); + // To prepare center bar path + canvas.save(); + canvas.translate(calcBTranslate(dbAnim), shadowReservedHeight); + final boolean isState2 = (state == STATE_SWITCH_ON2 || state == STATE_SWITCH_OFF2); + calcBPath(isState2 ? 1 - dbAnim : dbAnim); + // Use center bar path to draw shadow + if (hasShadow) { + paint.setStyle(Paint.Style.FILL); + paint.setShader(shadowGradient); + canvas.drawPath(bPath, paint); + paint.setShader(null); + } + canvas.translate(0, -shadowReservedHeight); + // draw bar + canvas.scale(0.98f, 0.98f, bWidth / 2, bWidth / 2); + paint.setStyle(Paint.Style.FILL); + paint.setColor(0xffffffff); + canvas.drawPath(bPath, paint); + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeWidth(bStrokeWidth * 0.5f); + paint.setColor(isOn ? colorPrimaryDark : colorOffDark); + canvas.drawPath(bPath, paint); + canvas.restore(); + + paint.reset(); + if (sAnim > 0 || bAnim > 0) invalidate(); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (!canEnable) + return super.onTouchEvent(event); + if ((state == STATE_SWITCH_ON || state == STATE_SWITCH_OFF) && (sAnim * bAnim == 0)) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + return true; + case MotionEvent.ACTION_UP: + lastState = state; + + bAnim = 1; + if (state == STATE_SWITCH_OFF) { + refreshState(STATE_SWITCH_OFF2); + listener.toggleToOn(this); + } else if (state == STATE_SWITCH_ON) { + refreshState(STATE_SWITCH_ON2); + listener.toggleToOff(this); + } + + if (mOnClickListener != null) { + mOnClickListener.onClick(this); + } + break; + } + } + return super.onTouchEvent(event); + } + + @Override + public void setOnClickListener(OnClickListener l) { + super.setOnClickListener(l); + mOnClickListener = l; + } + + public interface OnStateChangedListener { + void toggleToOn(SwitchView view); + + void toggleToOff(SwitchView view); + } + + private OnStateChangedListener listener = new OnStateChangedListener() { + @Override + public void toggleToOn(SwitchView view) { + toggleSwitch(true); + } + + @Override + public void toggleToOff(SwitchView view) { + toggleSwitch(false); + } + }; + + public void setOnStateChangedListener(OnStateChangedListener listener) { + if (listener == null) throw new IllegalArgumentException("empty listener"); + this.listener = listener; + } + + @Override + public Parcelable onSaveInstanceState() { + Parcelable superState = super.onSaveInstanceState(); + SavedState ss = new SavedState(superState); + ss.isOpened = isOpened; + return ss; + } + + @Override + public void onRestoreInstanceState(Parcelable state) { + SavedState ss = (SavedState) state; + super.onRestoreInstanceState(ss.getSuperState()); + this.isOpened = ss.isOpened; + this.state = this.isOpened ? STATE_SWITCH_ON : STATE_SWITCH_OFF; + invalidate(); + } + + private static final class SavedState extends BaseSavedState { + private boolean isOpened; + + SavedState(Parcelable superState) { + super(superState); + } + + private SavedState(Parcel in) { + super(in); + isOpened = 1 == in.readInt(); + } + + @Override + public void writeToParcel(Parcel out, int flags) { + super.writeToParcel(out, flags); + out.writeInt(isOpened ? 1 : 0); + } + + // fixed by Night99 https://github.com/g19980115 + @Override + public int describeContents() { + return 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + @Override + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/weight/segmentcontrol/RadiusDrawable.java b/mylibrary/src/main/java/com/dahe/mylibrary/weight/segmentcontrol/RadiusDrawable.java new file mode 100644 index 0000000..2569625 --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/weight/segmentcontrol/RadiusDrawable.java @@ -0,0 +1,139 @@ +package com.dahe.mylibrary.weight.segmentcontrol; + + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PixelFormat; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; + +// 圆角 Drawable 每个角的圆半径可以不同 (使用不同半径圆角图形的时候 使用这个类 以防止 系统提供的用 xml 实现的圆角 Drawable 在2.3 上 出现各个角位置错乱) + +/** + * Created by caifangmao on 15/4/22. + */ +public class RadiusDrawable extends Drawable { + + private int topLeftRadius; + private int topRightRadius; + private int bottomLeftRadius; + private int bottomRightRadius; + + private int left; + private int top; + private int right; + private int bottom; + + private final Paint paint; + private final boolean isStroke; + private int strokeWidth = 0; + private int strokeColor = Color.CYAN; + private int fillColor; + + private Path path; + + public RadiusDrawable(boolean isStroke) { + this(0, isStroke); + } + + public RadiusDrawable(int radius, boolean isStroke) { + setRadius(radius); + + paint = new Paint(Paint.ANTI_ALIAS_FLAG); + this.isStroke = isStroke; + } + + public void setStrokeWidth(int width) { + strokeWidth = width; + setBounds(left, top, right, bottom); + } + + public void setStrokeColor(int strokeColor) { + this.strokeColor = strokeColor; + } + + public void setFillColor(int fillColor) { + this.fillColor = fillColor; + } + + public void setRadius(int radius) { + this.topLeftRadius = this.topRightRadius = this.bottomLeftRadius = this.bottomRightRadius = radius; + } + + public void setRadius(int topLeftRadius, int topRightRadius, int bottomLeftRadius, int bottomRightRadius) { + this.topLeftRadius = topLeftRadius; + this.topRightRadius = topRightRadius; + this.bottomLeftRadius = bottomLeftRadius; + this.bottomRightRadius = bottomRightRadius; + } + + @Override + public void setBounds(int left, int top, int right, int bottom) { + super.setBounds(left, top, right, bottom); + + this.left = left; + this.top = top; + this.right = right; + this.bottom = bottom; + + if (isStroke) { + int halfStrokeWidth = strokeWidth / 2; + left += halfStrokeWidth; + top += halfStrokeWidth; + right -= halfStrokeWidth; + bottom -= halfStrokeWidth; + } + + path = new Path(); + path.moveTo(left + topLeftRadius, top); + path.lineTo(right - topRightRadius, top); + path.arcTo(new RectF(right - topRightRadius * 2, top, right, top + topRightRadius * 2), + -90, 90); + // path.quadTo(right, top, right, top + topRightRadius); + path.lineTo(right, bottom - bottomRightRadius); + path.arcTo(new RectF(right - bottomRightRadius * 2, bottom - bottomRightRadius * 2, right, + bottom), 0, 90); + // path.quadTo(right, bottom, right - bottomRightRadius, bottom); + path.lineTo(left + bottomLeftRadius, bottom); + path.arcTo(new RectF(left, bottom - bottomLeftRadius * 2, left + bottomLeftRadius * 2, + bottom), 90, 90); + // path.quadTo(left, bottom, left, bottom - bottomLeftRadius); + path.lineTo(left, top + topLeftRadius); + path.arcTo(new RectF(left, top, left + topLeftRadius * 2, top + topLeftRadius * 2), 180, 90); + // path.quadTo(left, top, left + topLeftRadius, top); + path.close(); + } + + @Override + public void draw(Canvas canvas) { + if (fillColor != 0) { + paint.setColor(fillColor); + paint.setStyle(Paint.Style.FILL); + canvas.drawPath(path, paint); + } + + if (strokeWidth > 0) { + paint.setColor(strokeColor); + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeJoin(Paint.Join.MITER); + paint.setStrokeWidth(strokeWidth); + canvas.drawPath(path, paint); + } + } + + @Override + public void setAlpha(int alpha) { + } + + @Override + public void setColorFilter(ColorFilter cf) { + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } +} diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/weight/segmentcontrol/SegmentControl.java b/mylibrary/src/main/java/com/dahe/mylibrary/weight/segmentcontrol/SegmentControl.java new file mode 100644 index 0000000..a5bf65d --- /dev/null +++ b/mylibrary/src/main/java/com/dahe/mylibrary/weight/segmentcontrol/SegmentControl.java @@ -0,0 +1,526 @@ +package com.dahe.mylibrary.weight.segmentcontrol; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.os.Build; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; + +import com.dahe.mylibrary.R; + + +/** + * Created by 7heaven on 15/4/22. + */ +public class SegmentControl extends View { + + private String[] mTexts; + private Rect[] mCacheBounds; + private Rect[] mTextBounds; + + private RadiusDrawable mBackgroundDrawable; + private RadiusDrawable mSelectedDrawable; + + private int mCurrentIndex; + + private int mTouchSlop; + private boolean inTapRegion; + private float mStartX; + private float mStartY; + private float mCurrentX; + private float mCurrentY; + + private int mHorizonGap; + private int mVerticalGap; + + /** 外边框的width */ + private int mBoundWidth = 4; + /** 内边框的width */ + private int mSeparatorWidth = mBoundWidth / 2; + + private int mSingleChildWidth; + private int mSingleChildHeight; + + private Paint mPaint; + + private int mTextSize; + private ColorStateList mBackgroundColors; + private ColorStateList mTextColors; + private int mCornerRadius; + + private int DEFAULT_SELECTED_COLOR = 0xFF32ADFF; + private int DEFAULT_NORMAL_COLOR = 0xFFFFFFFF; + + private Paint.FontMetrics mCachedFM; + + public enum Direction { + HORIZONTAL(0), VERTICAL(1); + + int value; + + Direction(int v) { + value = v; + } + } + + private Direction mDirection; + + public SegmentControl(Context context) { + this(context, null); + } + + public SegmentControl(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public SegmentControl(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SegmentControl); + + String textArray = ta.getString(R.styleable.SegmentControl_texts); + if (textArray != null) { + mTexts = textArray.split("\\|"); + } + + mTextSize = ta.getDimensionPixelSize(R.styleable.SegmentControl_android_textSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 14, context.getResources().getDisplayMetrics())); + mCornerRadius = ta.getDimensionPixelSize(R.styleable.SegmentControl_cornerRadius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, context.getResources().getDisplayMetrics())); + mDirection = Direction.values()[ta.getInt(R.styleable.SegmentControl_android_orientation, 0)]; + + mHorizonGap = ta.getDimensionPixelSize(R.styleable.SegmentControl_horizonGap, 0); + mVerticalGap = ta.getDimensionPixelSize(R.styleable.SegmentControl_verticalGap, 0); + + int gap = ta.getDimensionPixelSize(R.styleable.SegmentControl_gaps, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, context.getResources().getDisplayMetrics())); + + if(mHorizonGap == 0) { + mHorizonGap = gap; + } + if(mVerticalGap == 0) { + mVerticalGap = gap; + } + + mBackgroundDrawable = new RadiusDrawable(mCornerRadius, true); + mBackgroundDrawable.setStrokeWidth(2); + + DEFAULT_NORMAL_COLOR = ta.getColor(R.styleable.SegmentControl_normalColor, DEFAULT_NORMAL_COLOR); + DEFAULT_SELECTED_COLOR = ta.getColor(R.styleable.SegmentControl_selectedColor, DEFAULT_SELECTED_COLOR); + + mBackgroundColors = ta.getColorStateList(R.styleable.SegmentControl_backgroundColors); + mTextColors = ta.getColorStateList(R.styleable.SegmentControl_textColors); + if (mBackgroundColors == null) { + mBackgroundColors = new ColorStateList(new int[][]{{android.R.attr.state_selected}, {-android.R.attr.state_selected}}, new int[]{DEFAULT_SELECTED_COLOR, DEFAULT_NORMAL_COLOR}); + } + + if(mTextColors == null){ + mTextColors = new ColorStateList(new int[][]{{android.R.attr.state_selected}, {-android.R.attr.state_selected}}, new int[]{DEFAULT_NORMAL_COLOR, DEFAULT_SELECTED_COLOR}); + } + + mBoundWidth = ta.getDimensionPixelSize(R.styleable.SegmentControl_boundWidth, mBoundWidth); + mSeparatorWidth = ta.getDimensionPixelSize(R.styleable.SegmentControl_separatorWidth, mSeparatorWidth); + + ta.recycle(); + + mBackgroundDrawable = new RadiusDrawable(mCornerRadius, true); + mBackgroundDrawable.setStrokeWidth(mBoundWidth); + mBackgroundDrawable.setStrokeColor(getSelectedBGColor()); + mBackgroundDrawable.setFillColor(getNormalBGColor()); + + if (Build.VERSION.SDK_INT < 16) { + setBackgroundDrawable(mBackgroundDrawable); + } else { + setBackground(mBackgroundDrawable); + } + + mSelectedDrawable = new RadiusDrawable(false); + mSelectedDrawable.setFillColor(getSelectedBGColor()); + + mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mPaint.setTextSize(mTextSize); + mCachedFM = mPaint.getFontMetrics(); + + int touchSlop = 0; + if (context == null) { + touchSlop = ViewConfiguration.getTouchSlop(); + } else { + final ViewConfiguration config = ViewConfiguration.get(context); + touchSlop = config.getScaledTouchSlop(); + } + mTouchSlop = touchSlop * touchSlop; + inTapRegion = false; + } + + public void setText(String... texts) { + mTexts = texts; + if (mTexts != null) { + requestLayout(); + } + } + + /** + * 设置文字颜色 + * + * @param color 需要设置的颜色 + */ + public void setSelectedTextColors(ColorStateList color) { + mTextColors = color; + invalidate(); + } + + /** + * 设置背景颜色 + * + * @param colors 颜色 + */ + public void setColors(ColorStateList colors) { + mBackgroundColors = colors; + + if (mBackgroundDrawable != null) { + mBackgroundDrawable.setStrokeColor(getSelectedBGColor()); + mBackgroundDrawable.setFillColor(getNormalBGColor()); + } + + if (mSelectedDrawable != null) { + mSelectedDrawable.setFillColor(getSelectedBGColor()); + } + + invalidate(); + } + + public void setCornerRadius(int cornerRadius) { + mCornerRadius = cornerRadius; + + if (mBackgroundDrawable != null) { + mBackgroundDrawable.setRadius(cornerRadius); + } + + invalidate(); + } + + public void setDirection(Direction direction) { + Direction tDirection = mDirection; + + mDirection = direction; + + if (tDirection != direction) { + requestLayout(); + invalidate(); + } + } + + public void setTextSize(int textSize_sp) { + setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize_sp); + } + + public void setTextSize(int unit, int textSize) { + mPaint.setTextSize((int) (TypedValue.applyDimension(unit, textSize, getContext().getResources().getDisplayMetrics()))); + + if (textSize != mTextSize) { + mTextSize = textSize; + mCachedFM = mPaint.getFontMetrics(); + + requestLayout(); + } + } + + public void setSelectedIndex(int index) { + mCurrentIndex = index; + + if(mOnSegmentControlClickListener != null) { + mOnSegmentControlClickListener.onSegmentControlClick(index); + } + + invalidate(); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + int heightMode = MeasureSpec.getMode(heightMeasureSpec); + + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + int heightSize = MeasureSpec.getSize(heightMeasureSpec); + + int width = 0; + int height = 0; + + if (mTexts != null && mTexts.length > 0) { + + mSingleChildHeight = 0; + mSingleChildWidth = 0; + + if (mCacheBounds == null || mCacheBounds.length != mTexts.length) { + mCacheBounds = new Rect[mTexts.length]; + } + + if (mTextBounds == null || mTextBounds.length != mTexts.length) { + mTextBounds = new Rect[mTexts.length]; + } + + for (int i = 0; i < mTexts.length; i++) { + String text = mTexts[i]; + + if(text != null){ + + if(mTextBounds[i] == null) { + mTextBounds[i] = new Rect(); + } + + mPaint.getTextBounds(text, 0, text.length(), mTextBounds[i]); + + if(mSingleChildWidth < mTextBounds[i].width() + mHorizonGap * 2) { + mSingleChildWidth = mTextBounds[i].width() + mHorizonGap * 2; + } + if(mSingleChildHeight < mTextBounds[i].height() + mVerticalGap * 2) { + mSingleChildHeight = mTextBounds[i].height() + mVerticalGap * 2; + } + } + } + + switch (widthMode) { + case MeasureSpec.AT_MOST: + if (mDirection == Direction.HORIZONTAL) { + if (widthSize <= mSingleChildWidth * mTexts.length) { + mSingleChildWidth = widthSize / mTexts.length; + width = widthSize; + } else { + width = mSingleChildWidth * mTexts.length; + } + } else { + width = widthSize <= mSingleChildWidth ? widthSize : mSingleChildWidth; + } + break; + case MeasureSpec.EXACTLY: + width = widthSize; + break; + case MeasureSpec.UNSPECIFIED: + default: + if (mDirection == Direction.HORIZONTAL) { + width = mSingleChildWidth * mTexts.length; + } else { + width = mSingleChildWidth; + } + break; + } + + switch (heightMode) { + case MeasureSpec.AT_MOST: + if (mDirection == Direction.VERTICAL) { + if (heightSize <= mSingleChildHeight * mTexts.length) { + mSingleChildHeight = heightSize / mTexts.length; + height = heightSize; + } else { + height = mSingleChildHeight * mTexts.length; + } + } else { + height = heightSize <= mSingleChildHeight ? heightSize : mSingleChildHeight; + } + break; + case MeasureSpec.EXACTLY: + height = heightSize; + break; + case MeasureSpec.UNSPECIFIED: + default: + if (mDirection == Direction.VERTICAL) { + height = mSingleChildHeight * mTexts.length; + } else { + height = mSingleChildHeight; + } + + break; + } + + switch (mDirection) { + case HORIZONTAL: + if (mSingleChildWidth != width / mTexts.length) { + mSingleChildWidth = width / mTexts.length; + } + mSingleChildHeight = height; + break; + case VERTICAL: + if(mSingleChildHeight != height / mTexts.length) { + mSingleChildHeight = height / mTexts.length; + } + mSingleChildWidth = width; + break; + default: + break; + } + + for (int i = 0; i < mTexts.length; i++) { + + if (mCacheBounds[i] == null) { + mCacheBounds[i] = new Rect(); + } + + if (mDirection == Direction.HORIZONTAL) { + mCacheBounds[i].left = i * mSingleChildWidth; + mCacheBounds[i].top = 0; + } else { + mCacheBounds[i].left = 0; + mCacheBounds[i].top = i * mSingleChildHeight; + } + + mCacheBounds[i].right = mCacheBounds[i].left + mSingleChildWidth; + mCacheBounds[i].bottom = mCacheBounds[i].top + mSingleChildHeight; + } + } else { + width = widthMode == MeasureSpec.UNSPECIFIED ? 0 : widthSize; + height = heightMode == MeasureSpec.UNSPECIFIED ? 0 : heightSize; + } + + setMeasuredDimension(width, height); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + switch (event.getAction() & MotionEvent.ACTION_MASK) { + case MotionEvent.ACTION_DOWN: + inTapRegion = true; + + mStartX = event.getX(); + mStartY = event.getY(); + break; + + case MotionEvent.ACTION_MOVE: + mCurrentX = event.getX(); + mCurrentY = event.getY(); + + int dx = (int) (mCurrentX - mStartX); + int dy = (int) (mCurrentY - mStartY); + + int distance = dx * dx + dy * dy; + + if (distance > mTouchSlop) { + inTapRegion = false; + } + break; + + case MotionEvent.ACTION_UP: + if (inTapRegion) { + int index = 0; + if (mDirection == Direction.HORIZONTAL) { + index = (int) (mStartX / mSingleChildWidth); + } else { + index = (int) (mStartY / mSingleChildHeight); + } + + setSelectedIndex(index); + } + break; + default: + break; + } + return true; + } + + private int getSelectedTextColor(){ + return mTextColors.getColorForState(new int[]{android.R.attr.state_selected}, DEFAULT_NORMAL_COLOR); + } + + private int getNormalTextColor(){ + return mTextColors.getColorForState(new int[]{-android.R.attr.state_selected}, DEFAULT_SELECTED_COLOR); + } + + private int getSelectedBGColor(){ + return mBackgroundColors.getColorForState(new int[]{android.R.attr.state_selected}, DEFAULT_SELECTED_COLOR); + } + + private int getNormalBGColor(){ + return mBackgroundColors.getColorForState(new int[]{-android.R.attr.state_selected}, DEFAULT_NORMAL_COLOR); + } + + @Override + public void onDraw(Canvas canvas) { + super.onDraw(canvas); + + if (mTexts != null && mTexts.length > 0) { + + for (int i = 0; i < mTexts.length; i++) { + + //draw separate lines + if (i < mTexts.length - 1) { + mPaint.setColor(getSelectedBGColor()); + mPaint.setStrokeWidth(mSeparatorWidth); + if (mDirection == Direction.HORIZONTAL) { + canvas.drawLine(mCacheBounds[i].right, 0, mCacheBounds[i].right, getHeight(), mPaint); + } else { + canvas.drawLine(mCacheBounds[i].left, mSingleChildHeight * (i + 1), mCacheBounds[i].right, mSingleChildHeight * (i + 1), mPaint); + } + } + + //draw selected drawable + if (i == mCurrentIndex && mSelectedDrawable != null) { + int topLeftRadius = 0; + int topRightRadius = 0; + int bottomLeftRadius = 0; + int bottomRightRadius = 0; + + if(mTexts.length == 1){ + topLeftRadius = mCornerRadius; + bottomLeftRadius = mCornerRadius; + topRightRadius = mCornerRadius; + bottomRightRadius = mCornerRadius; + }else{ + if (mDirection == Direction.HORIZONTAL) { + if (i == 0) { + topLeftRadius = mCornerRadius; + bottomLeftRadius = mCornerRadius; + } else if (i == mTexts.length - 1) { + topRightRadius = mCornerRadius; + bottomRightRadius = mCornerRadius; + } + } else { + if (i == 0) { + topLeftRadius = mCornerRadius; + topRightRadius = mCornerRadius; + } else if (i == mTexts.length - 1) { + bottomLeftRadius = mCornerRadius; + bottomRightRadius = mCornerRadius; + } + } + } + + mSelectedDrawable.setRadius(topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); + mSelectedDrawable.setBounds(mCacheBounds[i]); + mSelectedDrawable.draw(canvas); + + mPaint.setColor(getSelectedTextColor()); + } else { + mPaint.setColor(getNormalTextColor()); + } + + //draw texts + + float baseline = mCacheBounds[i].top + ((mSingleChildHeight - mCachedFM.ascent + mCachedFM.descent) / 2) - mCachedFM.descent; + canvas.drawText(mTexts[i], mCacheBounds[i].left + (mSingleChildWidth - mTextBounds[i].width()) / 2, baseline, mPaint); + + } + } + } + + // ========================================================= + // OnSegmentControlClickListener + // ========================================================= + private OnSegmentControlClickListener mOnSegmentControlClickListener; + + public void setOnSegmentControlClickListener(OnSegmentControlClickListener listener) { + mOnSegmentControlClickListener = listener; + } + + public OnSegmentControlClickListener getOnSegmentControlClicklistener() { + return mOnSegmentControlClickListener; + } + + public interface OnSegmentControlClickListener { + void onSegmentControlClick(int index); + } +} diff --git a/mylibrary/src/main/res/anim/anim_bottom_in.xml b/mylibrary/src/main/res/anim/anim_bottom_in.xml new file mode 100644 index 0000000..e1191a5 --- /dev/null +++ b/mylibrary/src/main/res/anim/anim_bottom_in.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/anim/anim_bottom_out.xml b/mylibrary/src/main/res/anim/anim_bottom_out.xml new file mode 100644 index 0000000..2c2299b --- /dev/null +++ b/mylibrary/src/main/res/anim/anim_bottom_out.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/color/select_text_color.xml b/mylibrary/src/main/res/color/select_text_color.xml new file mode 100644 index 0000000..e3e3992 --- /dev/null +++ b/mylibrary/src/main/res/color/select_text_color.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable-hdpi/left.png b/mylibrary/src/main/res/drawable-hdpi/left.png new file mode 100644 index 0000000000000000000000000000000000000000..6a9e644c277cc549ff4c9d1cb6e94a9fda05a189 GIT binary patch literal 489 zcmVB`C`mCgGBP0NWMZNe85m%wh*FY6P7|lC ztM0d+^1eK|-)nRauKs)Pwb#9__|H>SGcgbEl6)KulmB5?)hryv23$+Baa`b4H4&%L zfYWd{$O`0*!Upud=saS_oXx4jkJs3Pt4Y51f>+f_ zT*PcNU036Jk{`o>+nrH6uc{Te(fRm2b|*PMEOg}FSn#vh(iOje%}KtD7koKxc7FbV z{YlP^3%o(9Y8kF{zW#-_+)KSRAL+2FR^bE|;0^ZTa*}VuOz|%(PQeuO%bg_svZY(_^yYUQ?xNrcb|ksiE4T*a znS^6#vD-rH85SpL(eTF^I&udJv}8Pqt!UHSPqJ`a;GIM*A)Ed!(_7xOLj5}*n4rBz fBd`Cb(cr%U?s|?GF9;(E00000NkvXXu0mjfoXF}0 literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xhdpi/black_back.png b/mylibrary/src/main/res/drawable-xhdpi/black_back.png new file mode 100644 index 0000000000000000000000000000000000000000..c12c77fdc4b5f68383a6ccb6a0b6a353c8a6a3cc GIT binary patch literal 1331 zcmeAS@N?(olHy`uVBq!ia0vp^fv4 zq}24xJX@vryZ0+8WTx0Eg`4^s_!c;)W@LI)6{QAO`Gq7`WhYyvDB0U7*i={n4aiL` zNmQuF&B-gas<2f8n`;GRgM{^!6u?SKvTcwn`Gt*5rG`3JMx70H< zwX`rY(NQomFf`LQu+%p+(KRr%GO)BVFjRm7C7^9ZDQQ+gE^bh}fIM5JjFOT9D}DX) z@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7^KE~&-IMVSR9nfZANAQKal z@=Hr>m4GgVcpt!dA^}sqE0q(%_)qQ35@7Kzx@(@Mpjxu%u9$-95lzMA4W{4A^;cToYMs`}&Mc zM+fB^u5K}YVl63?%4nj~r0$)mkd+tsd@=Lg#Y_v_UcEcf&Rlv(rfPa_>#K&}zB4VD%{_M%7-YU{hBCE4>n#f z$aP83u2Rk*$@RWT#=A8;xBV2KeSiPO1J}70F>uXb*)W0gf}eY%;Gr{Ten+}YIiRIk z6*q_N$V&&tG>0vxGmdKI;Vst0Dfvxwg3PC literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xhdpi/ic_add_image.png b/mylibrary/src/main/res/drawable-xhdpi/ic_add_image.png new file mode 100644 index 0000000000000000000000000000000000000000..38e38da428c8c1236fa8faa8e8345971f1d31524 GIT binary patch literal 897 zcmeAS@N?(olHy`uVBq!ia0vp^9U#oX1|)5EEd~iN76-XIF|0c$^OAvq+1k^^F{Fa= z?HymgXht5_#3;kFTATi>rgG2R!y3S8+VP?Isppf3e^v{ROv{;H{Uzbh@8Z32_v8LJ zKM-fCum5@HIL990ioJyvbN#me|J8NibfL_95gW%70-ORWj{;RV*p(QYTx_~n9y+Kv zOz3c*s36n9!XflgL#Ty$B7>unoNH5of{=p8k;NVYd@f8ZofRUShZ;Q^6a@Q~94*K* zM85v6{BAK3{pqLgPJRCQ=eyr)?^iVC`0lGPckEiQZJS_9_NSw}IfGcXZtYcwo~(b* zcY@N2wYe-eXVrYnYZ7tH%~d{e?MZjJ@Dh%!Y-z`BYVmt!E4T(k-{#n4`t#9U7R{zx zx7;SIJt_WP%|r0YH8WZpUH)6TZQs6|%XfS~e0yH%`gi8Cl}$D=TW>OR7+LRc&-b6u zt~}3n!Qb);@8)mZ{$t<2b02l8?|ysz>lNoE*SZriO+1{dvVEIMCdwO4S8#566*XBQ z_DTC0)e{pI?7F7nA^uabnA1pQ#X8f$r~J-0a~@l6^?Z?EmYn_*=I{LR#h$S#K#|JH yg}5~L@$vfK{f`}(8}nIg9QP@HJebb(pW!EyxcY+UHqO92#o+1c=d#Wzp$Py7`D)q# literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xhdpi/icon_upload.png b/mylibrary/src/main/res/drawable-xhdpi/icon_upload.png new file mode 100644 index 0000000000000000000000000000000000000000..d8ff158b1713c8698534c9be0995a5c3dc57d2ca GIT binary patch literal 1421 zcmeAS@N?(olHy`uVBq!ia0vp^0U*r53?z4+XPVEz!1yV^C&U%VWnlQv(D0uj6iDu8 zNIS#OaFrqVHbcXGhQh}TY0nr+UVymecNq%qGgLfe$bQ05d=n_boqvz3-~m_JBhIqh zoJDsy^6qjJ+-EPn&0ctiz4R`7(OtIU`)mad*oq&r72akmyvtT{kF^Mh9^z7g zfo^~p0@e;P5bOY;2|!Ol+yG(&-2iqEPy}oa$Za4t*bunGitYm4hGYWF7a)~j2SEG< zVS}}U#i2$)3b0A9?%sRw@X_NZ&z`?{`RdKvcke%Z{Pg+D*Kgl{ z{r>a!Uus+0djuAMa)geB22R#;d9%!{I^o2-^K7C*fgDKY;H_5G9&bDiL zZC0&a_s!Taqxr>*21-j!91?7f<33d3B#_a_RjQEURiF z+dRd}0$D>oh$h6G`?mOanU!H)puVU>Yix%`9$#?9HbKGJD;Z8zDlWNJaOiBNz$;C5 zuh!{@CzSLD$}KyvLBmBe;FV^}A&~ zJ=GGFxWj+47>C`d2BWC(JF#*mN85+^-jTh-uo zwm4zZ%cVjqzGVt0iIfNNZuyk4mwCU6sQD$XjJ3<(J-D@K(Ie(?`%6+QBtg(^uvou{3P!4X3r+l%5)!{+h!iv(U|*VaeX5X1Oa3MEHUyKXh`*;STJcnEPXC zN{19r?xB`F;yw}Ha*Hg!Z8cVWyOeLn4z1Z$O@Fu#&RfPMzU+^G9h1qS<8vHNPcjD; NtDdfYF6*2UngD?seJ%h1 literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xhdpi/left.png b/mylibrary/src/main/res/drawable-xhdpi/left.png new file mode 100644 index 0000000000000000000000000000000000000000..fa0ec3d651390fdf49013d3b3a5ba6def0ca4355 GIT binary patch literal 575 zcmV-F0>J%=P)=6u~3wSg_M+p#1Kh@1!@+Q9XnZwh$M+p zQWm0*zB*H)m~UZ7%}u0xJ^s zQPPru!nPLzH-NDWnvt}6V6g4^z!hL?hP(ilOZq$z*mfM#d0=M-ya9$Jy>GfZ)n{z` zB(OUJ0vnO^x(SWvRj}=&z<~^iZ5@{MyacU+Z65@VWWd*iJ}pIC!?yPTCoN|~|;bi+Auq;C-C7tOcrpayKn6g(=eygj$p$Q&IRVPZ`>{d@m zI#(^0toV;)uL164=Ny-7yQHYS)uSk7+TH|Q&%)^^utn1CTDb^LD<21@fq4mwSRRu! zQ-c@737-H?&&ghEB|U13w}KNs1subl>bp9@36D~F4cMIF40>PlJY^)(q7x$7dYXO&*Qgc2-q*_(m#QlF4NrSzX5{xp&!z7Kgs|A N002ovPDHLkV1gbz1cLwo literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xxhdpi/cars.png b/mylibrary/src/main/res/drawable-xxhdpi/cars.png new file mode 100644 index 0000000000000000000000000000000000000000..c0959a8f5b0aa3098578b77b3b946aef20efb252 GIT binary patch literal 1339 zcmV-B1;qM^P)cN>OUHY88E`G_6QMii(t? z4^^tRiWMpPP+!C#N+_ATyTmTqAQ-9IYE5m6cGBIMIda2pnI`)&t83Y2QmjE%pcRS@B1CLAT8hP9ss=Iq|0tGBCYSoY|2lxX z0odnBfHNYpyQ8Dy*|D*)*wE0>zLAlU zuo_%5feC1lLfCk$f`#KC-&~$8${un32fGH$8nwqum!+^0>}vftF_kqni{OPx3|5sv(wa< zYYHGj@&(s*UutTwf@%tYE`o^2=2R+m&ZpKt2}LH8$%KeplF#S6+S=Lz5jmAeB#w=a zj?O(?D;5ZIt9t+@t$!8-L7Q#cGx>b}cqWrEiQ$}-J~%ko8;0S*x`GW146F>pa23g0 z0W1*_55Tu3Lxo}ZPCA|bv0AxPd|v|W7m{Yt%xBE601lAc<$2!zY&M%K_NzOXQfdv! ztpF~LlsLut@*=XI(%UBQ%64#`gdTv5qslAB%E zjdisU1FSfei3+8){;qCd0CtGTF_MD-?u?xL833OHxC+2s#jjuhe~5^=<*M39-Uwi2 zBz2oT`mu=oO!77WH$(>cLPWltJqzJAFWy|mRlOfajpUI5dgE{%eB*%Wvv?@AAh@=G{yHy zsYgh@2B5QCACf=ha=8@~6BED19k-?*CHnjOZzj2oEwQc)8Q&E$=7QnQKj9QkpT}0Aa>(jM3U~Elc z+tt-IC?Y0>-wt4rh)i0RwI>LI_tNR~VE|QcrYi2STAgZC`;bp~EnCqn70niV4tUpqhGrXHLASJYoPZt)M7g4-8DuFzAvm!; zp0NXdY0x8yJ>M5UXZ++LG=5Oy{MZPX8Uf6_2jBp}3xHc9a(}&KV3Hi<1xu@3?*w(dCqYBLLSS z`tJNVeg+A#&!0@@wsh_HwyD4?4d=d!CJ8KVWf z3p`3dZ3$NJNdjs~u!K(*P+EdDyhuPP2_@jg0<0yJg3l6QC7~pIwg7DjrQuZsXi2C6 zuO=W@LM?bz0a6KF8aeeFo_UrToe9R~@Pelq+qAn*ec7!pKsXX&B&frye+7mV$|J!9 z-c*3%NHBvp7oZ@)6uyXn3<>7&8v!Xlh{R0OzH2fkL-SE!@*3<#WWx8&m`X4cpagF& z!9;*Eyr~3r0Y>m<5>y2U;Md<~F(iTScbnwgD}6il_o<8k4FHWcBr>uEXa=s?R;-LH z0TuyUv^gh3EWk2Q%eKcdL;^|#SfUTnVyIML!c}B)+MF~3O2TKXCz2#Y3#b8KLPC^) zn()>Vf&!KRZz*B3Nop!dSkjXp$EX?GRJ}m;O;Mp#R!f4fUSM1-5sD@0wG(PA<-9;b zuwJ0;&C<-={C4@~3ntnwndufF?G{Z9GA>`)+{L)!DrLqld2LqN+(1IRg_9+pR_(rm hi=o;9TKC_)fHx?`2w#L_olXD%002ovPDHLkV1kYZLc0I} literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xxhdpi/check_nor.png b/mylibrary/src/main/res/drawable-xxhdpi/check_nor.png new file mode 100644 index 0000000000000000000000000000000000000000..7b92670395ac66fc4c9760823bd0e3e7c8cdbb1c GIT binary patch literal 869 zcmeAS@N?(olHy`uVBq!ia0vp^W+2SL1|)l2v+go5Fza}_IEG|6znyj7U)WLP`2E>; zlf);fIdJQ4n=;#7U)to}pTYxjRo~ruW=QB)d`z(UvWQ*3=%dmxdG+&E85RS>9!Xelx!lsv#n)vG!vU@2oW|mRx>CLCRE0X{9=_LI&!1)_In8hR`hs)I z1r1YYJv*9U(9!6?z;oE*?4ACY*~NV8UOR2Rxx{bz=jM)0E?*R9pRGHeVwCissh*=) zM!liqvdfn#hSMbEaQ}55Zqq=?jc6;xnp9c>fTylr={I5AydE8~s zPZsCZ*20F*~wl4Db zSr}H;^5e*t2Mgx4`upq+t8)28Dd(T~5u57XCuh6u_2aKreJ;A&T*i?px4ZMwzVNkS z&n1%Q8Ehyxcc0>y*T7wuakQQR&fZ#dfZXW@}g@@aXTvYd8Py-`Mx~ zi*O*5V7|ab5v4e`1__2aQ{QgkWw7te5ET^fc%iK%mV0~JyGzXH^({DWYhLx8a~PO? O7(8A5T-G@yGywpz(UemF literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xxhdpi/check_sel.png b/mylibrary/src/main/res/drawable-xxhdpi/check_sel.png new file mode 100644 index 0000000000000000000000000000000000000000..b88f5e3e84b2479f3ba30c18297bfb76752de369 GIT binary patch literal 1650 zcmV-&295cNP)3$g6vzK(_8Gc_&U9L!Ee%wlNJS&21~dW^gC-h`s6a~ugc^e+)F7K86#^(9u!O(| zz_JyPO@bg2MG=(-rIA!7P__mstzBlO&~}ziJ9EvQ=5?9Z`uaMp%uKu=-@DuI{m(u3 zyn7F!o09Z;x!$d{r+}#@DZr*OhOr8Wrk|g?!B9nn5+CRcsO6llDemsQBgw9= z#wF3iJf<+0m1e@{ox>Pj0x$%CxL!X~NOaEtR1o1b!1mOnjk$2{7z__r5SgPBoM2d5JHWkN zfNKTIV+zxatMiGF4=}yVZbPIxxfpqKt!WuMxLNwa%-L7Q`xqT0ASFa**{f+V;I4w$ z%$mZCBI4f9qkfRj2n)hsO-TVWBHE#8idjsi?2?hhlxG1XNwo@-_xBj7rjT*gm3I|H zTO&X%;kz>*V++ZgWjVosSHeV%9!-;gugR2UxkJFv9<>OQN(}gm%-I$Wzgf(=hpW9PyIq?*;>%JIUL%0E?y%_r}N9~g%iHAI80Ic5w? zREq$P7BynY?%MDJ8#zRSby-F{Ib7GKltAJ3FhA6(Vn=v^B^gyHSd@TA25Cf4EnbGg z^9|T|+zw}xwD$;!HO9@4uPJVRT(Q97^)Y-??7+(XHZ;0A9c^^0Tu6ZNwZzRYbA%p> zfMX+13&Y_H4fyPG zNg7NaAC1@n3Y@y+KvAg+?q+G5540KH*U)%1wk(K8#!zt#&Y{khIIwh&RW_7t#m1&; zv14HZ_*dqo(e1;g6Lr}Ca|4=W!ljs0Ses?Sv*~&$6rHiTqd0!C5$liIQRk4SRIe0U zJIjRG6QeuLqTcDlvb|P(`-ij(78(wWQsRsE%y>LiCxY@Z_@UMvvBTczm2~UfRgh(h zt7jN7cXEuVFRoV3wrc!(%>`~k-44c&m5nNFo*(burveLyI&X1e$!@DZCJd&?0!vTQ zVArAqBo0)G#;mlrV8uQwe!1!bpI}#IaGVNjW*RXm!vJM~`L()qC)OOc!CD_2lNNTrC0c4zo*i4A}HRL?^B-~vZ1yQ zpk#yb2K-CE`AjsHzZQoWeZXf2aI?~bxm&7n&(m}HDUZH@gXyZDk^p3{arPv zz8}0&y>cExBdwb7)}$DGFl`{zD)B|kZ#UdnQD{Y3RkPoN=FKqTg(nP91?;}uWWT%Y zMBX7As_LYFMdYkGS!=9g#~Kx3-jo)H{5T|F;&rZvCQI@Y4#uhseD~irkC8 zNWH3!*voZOcIilBEfJIs!73Q3pKncI(bnfP#v&tu1=y*ocQ1~>lq2QLn!@y=_9U@e zR~8UcejeUQV#u|ojc!j8^KXX{nbs$4^gI#MshJ0+SQ%D{nB-e;HFyfTPQ(=8cUKE-4u(Nq9q0Ssb*_yQ~V&`z=k w0z3fz22kQ<> z$!{E05XQf%26FY-J|e^)6b{)G176}wkZep4C{BXx_M09lEC&KM;lLtdXJJX$|C?|C z#4+yfITGW3g=*Aey?O3+G)^C6UXtgh`bMADqsJx52U{<)Z0-M z-95=5b-UfAEXy=99cP_CXk%mJED?P{L^IBfLn2yElH}o}Bek}+c4~HZb}q}ZuK@(k znoj_{LB^ODvMie?qK^Q$Pzf{Nh~s#7QcwyrH8r(NL^r+2JYnW_01q^gp-|S^GXPYk z=N;;Vh^}QktfZ>Jr_N=_>%wIq%*Vk=0(W_d`)$ zmICF8z5qbwn|2c&!1Xju_sXDhm`f^?_g~GKb!NWrN2XLVm)dck%H-}+i|1QW6x}b{ zr7>nPZwKy1N@a52Q5vBF`9Ak{d&tac<442YYGh_+W-eN5)lEkm5Rq8jR3=kvpgQ@O zc{h$@>U28CWKtL+x>_YuYoMX~0GzefYVjPAkD1r3wb}+g@uGOZ%$kSC+*DR*8%gHn z)tt3fi>I3(hxs!jG6g}fVvH$t(WPjCMR zV1b!`ZVOXc7^|9T-VQDh(KiJ^D&HbA|M*ORa+oC|(n-(FBXpslzaQ z9l*8+qcZ8ceD|#yW4^13wtufNP~HyC1GwWYtVM5?nFDL>PC@Zh1N_u9QjLIem_+~| z6!f)$G`dr3tyb>RXPQ7Y0y4(DRQ zqiSV2s2e}VlAwvit;dftneyILo1}FnD3kA4gsNoHqi$OpZ*Fet5$n@}GErE~i-vq1 zu0HhLBqG;>AlPf-6gP1z3Td35#YXy_e++sRz-I-WeC$@Ba22g)P{UmL+=F6Kv(y&w zW)wx=*4eem{jII7c@e3UZ*Y_@87K58eN8)hTbat>@)38*TI=`0qj6>Mv4NSttecmc zM4-tt3N<}FeL+M(D+anX2R~I21hA96D{SRcGn-E;Ijr(lA5FJg3fNS@tnAKNXRc{{fVqMZzFi R8(IJW002ovPDHLkV1jkG3qJq= literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xxhdpi/empty.png b/mylibrary/src/main/res/drawable-xxhdpi/empty.png new file mode 100644 index 0000000000000000000000000000000000000000..2bc4195912a27bce77a1be85b3f6a2ea57e422b2 GIT binary patch literal 54696 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%0Aw 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 tQqsXofV5XOZovb=IBk$<8#EIoUYA4L6qxqd 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 literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xxhdpi/icon_refuse.png b/mylibrary/src/main/res/drawable-xxhdpi/icon_refuse.png new file mode 100644 index 0000000000000000000000000000000000000000..78a9c52d6c7375b06d3b0cb82425301fdc984743 GIT binary patch literal 1173 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw3=&b&bYNg$oD|>_;tJ&choI2V|Hj7uwYC4N zc>cGv1hXCfTU-A(cKL7M@L$&kBxq*#-`MuQq4j@#%m1c!|BbEx8(RI>12U}s8(IE0 zu=}rX^WV_+zrOW<6DyEPBd`LXG7!V=zlqI%BRh}+kb0mjP%%&nOd3EGgGrEL8<62p zHDCo0(?BGU3p59)0A>QvK#+Q{AW#dG4b~1)304MI53vqNf)LPmFkK)9lHm|p1PL<) zZXi@6L_3@Wdk4D|*kMq6;p(w4!ex1LfU(kA666=mz{teR%Er#g#ly=lASfg(DJ3l{ zC$FfiqN=8)tz%?iX=7{W;NGPMb zUcY(!?)}Ga-+%o4_507?ZTc;T7#NszJzX3_JdVG;{?lICQH0@x;1-W1UCWk+2(I0A zHPZdUf+eD*BAKo-rAO{MyKGV1UHQM<^vJo}wVSQ$9ci!y7LcP-Go|itgsz^LK|Jz;Y%12K|qrUq$*R1)i&Y>KV zk@q{)p!0;b@GMKtXA>*5w@3yjh-R(+F!P|*x$KPJR+^0uS2S!o7q1|y_^P*-<>U*q zTSl&8?w@#nbWfXGxHsbXXZ5bQysX8Jdv&kXSxh=Rqju`{!{WlLcJ$6#eOOL+`{(+c z_`}nt7R6s%c{n;|9p~#Qsh97xUAGVsF zZuj>zt~OZDo6dXH*#6YpM&-ZVcb{(Znz^yy`>AWW@`cGaragVb&t4j7+j$~l>#Tih z+2>RX=D%pl3)Ou)WykuA&gh8xWuDbdm#@gpImYr(x;eI8d zw8Q9o%%(^b literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xxhdpi/id_select.png b/mylibrary/src/main/res/drawable-xxhdpi/id_select.png new file mode 100644 index 0000000000000000000000000000000000000000..c2f3394e7566ff9039df04dab69ef1bdf5d7e0f1 GIT binary patch literal 6680 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 literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xxhdpi/id_select_loading.png b/mylibrary/src/main/res/drawable-xxhdpi/id_select_loading.png new file mode 100644 index 0000000000000000000000000000000000000000..fa1a413a934b50afbd2c11505b63538e21bbb642 GIT binary patch literal 6169 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 literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xxhdpi/id_select_z.png b/mylibrary/src/main/res/drawable-xxhdpi/id_select_z.png new file mode 100644 index 0000000000000000000000000000000000000000..629b84ddddc11548dc1ab2720a59b4bc569ae23f GIT binary patch literal 5435 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 U`gD^rxhM)S)HT&9zXpH$4-`e)VE_OC literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xxhdpi/left.png b/mylibrary/src/main/res/drawable-xxhdpi/left.png new file mode 100644 index 0000000000000000000000000000000000000000..78dfb147f076908aca9db808299ea505b25fd324 GIT binary patch literal 1006 zcmV?Ykw3Nw1>Vo^l-AQ9<?7@ zfdxe%K4eNMqS=c?5>!U?U}akt>^~e1$CxwoonhLK!v)Pxmz9asJp~G*LV7a6} zMglq_P6OrvuL74gK>3e6C+Vj)z<#!qOlOAg&8EA&0cuN54Ns5O(G~Qqz`MXzHKG&1 zb~mM@Us}`V7m7ni#B^XCa9sn`r@&K^4)qIMygVY}HsEdG+6JhvfccV+4gy>hIwGzI zHUd){#@bF`p`;^&0vCghh#P>{f!iCPz6Krxc1wzpfQ|^4!sdnyo9{4iH*lyF@W7dl zh)J2@*|iKhqX&TdC4E~WyVW!Lo*oe~F&D>ufEP(MegKvLpGoqnE*gD7M}#+=o9@nr z1@#+n53oy;=W_9A4IL2|11|#)HDvfle=h0s;-r-WTR}&}`M`_7BfuFou%CgYz=x9l z842i!uy9`sECMX(t6|6ofNhej-a3t*GaV5Nb3LC|BXSLUHCqG?CE7r*0GZ|b) z@UW!56k9+4vJLe76z#6-YFNNOE6E~hDA5MmPI~nzn$WY@mg;>;e|1gXGqgeS&SGUQ zj)e_KvC6Y(vdXibE*b+tXQ^D7Cbr1{Sc}{R z`0A^O0q}1Q44vRtr>>sakkaqcx$Gzo72|{)v%MGM% z-T*vZ>ai_1r&oXL=n~pz`})Af;fe;b53E)CsqxOBGuu9YMmDG2do}EKY#f$K`n^rM zJB3bgYZJSkRSg&Ge#DpReoN4EbPk>1R)co$uK-qw)%af0H9ZrT+K9dUV7_~?`*Cwt zedbb%7 literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xxhdpi/message.png b/mylibrary/src/main/res/drawable-xxhdpi/message.png new file mode 100644 index 0000000000000000000000000000000000000000..b976b4e76b01653699ae4bb8afb82f65f9058a24 GIT binary patch literal 1518 zcmVcH?F{!8$Q$?t>)R0L0L8%Jj4^t3hM2#s*BxX{I zM9ef&sUhaEh8mW9tn+eu`|fbwJy-ijS90=_d(Yi_eS59_t+l`XM2!{^0yY2+22KR_ z$l+%Lw*oVPFC|4?(|W>MES=vAxCGb-XdK&4KLcC{%&H4Sod7ll9smaS<9xA51~Cgb zLel4TtX!P{&Ic|nIrTU2Bd`pxTK+A*zChBHB?dr5EDwALY@Sa21v~-V0xXyNVSixR z{QhHLTSEtZO39f&fuDdi z^Rpj-HA)fi$AcxAow~BFA`lU)BxN2A98=MgdjUT)CH+$Iw|%b<7(hhq09+01nJZm& zET@q-`OClrN$(B>MAb=&h?O$GuL9OBO=^dJ2EKE#0^SF{%I{s=wg=V+)=pL`&;1Q> zHZWb%Z&iR)0uT`^0_Oo|0_&6}vICDM^Slbokz^X}vxqRAZk^TnK;W>31^5=Y7MLRG z_fA1{3?L#*hf{&m0Ryqw$!8PPJCYoMwiXet3p?g`LrXQnj^7AO?37|V0+7z1k`u0) z9{vj41)M9%X;axE!s&Dca4g`|w9N-512;%Ao3*q~0hlJu<6Gru-h7V6v?}55&y$E) z0XQe0f_6VLt4VS?b_XDvw5PK{^I%?;Yk-Top}(?MNyirhX92G2HmByWc1>T~2t>rV zY=w(CO?x9Hx!Trd5wRiga5jU*xZ@<<)@qWL03u>N;BjF0Qr-`jW&q_3Mz)(*hvY{=Hi0emPqsgWY03b-)8Ue3K=)|LM6!#DuIf zrc}>8NYYzX0Sp74${)E!I8Bl(Z_h0vT$!)WrqA>3C&{&_QUpc<#qKv7n3K)ZJ-3J$ zm9?i}zfsNRZk0kFvm-Ug~&9H>1*}0D2LQr4jI|=0;k&2L_U2 zU8PX=|2`=lm#Tw(Slle+!ghxRgU0j0LM)Wd`}AdeI+TQt*lqx&z;u&C0VrX zxn(QwdxSAr%&b2ZzAmI}Hv)JY*eN~y6gU-lQIcDU|J@?Ot%NU4EVXQs4p_c%qxr8j z0&wSN{m1qgFrrtduTEDZPiZrNL-IEZBo(^UA^fWh?Iz`QT-gm9c4EQE6Ly{w~khMAw_&ZP7E((VOJ}a*d_`rWq?wkIcaz6X= z&*y9(Q{5u?YPOYm_2)N}7~4vV?Q$m~+YiF%8+pKDjPw}>>GnOoURIGF(({T#5Tlt37brjqu6$Qp& z{{$%5!tCZsTBM^>ZHT1u&1RJ;``+z30>wxXadNVkuTxu@?-neO-83MN8-7$L0H@N} zEQG~HNTZKVsmrZ6belTGz_kJJfcY;6F8#ixH#_Z`%9>R*Z**&(^E$o%>Lfz{0DtrX UPn^|`4*&oF07*qoM6N<$f}7LP`v3p{ literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xxhdpi/ok.png b/mylibrary/src/main/res/drawable-xxhdpi/ok.png new file mode 100644 index 0000000000000000000000000000000000000000..e64bc5bdddf9db6eeef9f942ff590f1d10c337d1 GIT binary patch literal 4040 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�)HlAI@}`)vzGYl0GI?6EiRcD>QRo zG&qEQ0{DveL=*u$q**D`-8G{eSC(#!ME{594o2Z9auz4pfoleOuGL}RDPRLHf+pZg z<)pFTwnP9UjH{Ms-qUw+Tpf53KnAXd$J71p1SqvnHBZVkNSOgD21t=^n+Pb%_F9^V z+O8tNasY|r%9Mj!V}lcD0hQE_7i^)jCQ$NHLSZfI_!YXtNi`NFv#8^AeQtb?^R|$j zQd6(|H<)!bxyT(}JPQVqaL zye`xX3}_+sQ}Ot%fa88LGpmut8lm1@Z^F&{x8bG$7Kj{{61Y6TAIL(FhkgMl4{#&z zVaO@5<0rCTO3ma>B(QwGERX_#CEqLTMBith&tZg9K#_Qui*tPXy=Y7FbI6C1!Ar_t zg>tgc?DL)Td>MZqCIEpK&Dz$(dOc+fcJIBvoH)bQwF;8+b}qbSiVBm$Dj?wQmn3wP zvKlBLS0n$afF7$Y2`oTA8c;eWK*5@lZk;tC!mVQ|uWM4c!|M^QJL$?0967My0RqPY zDk=yND2#M#FF<9y?h-icC32Y!yD6jr04EqdKJvX5rFXsrQ?C@GKQYk!Uj`l6)GIsD zC)2M8S_(+1;=b9BW?ld?QXH=YW_sYk0g?KQF$IG##{iIGgs@~1 z24-Q=H0;SPY#vzTFziIH0TiC}j|a^|zD2=k;tpPl-tP+RfAdY)|NIMm5LBB|B$RYU zhz2E{uXMSZFADx0B7d=f1%OP^vS448&PRo2sjpxO`fQpM08?`e6}5l1yx*!dJ2rNNWfNzi+#+369ahE*G9V-U~pqw6QB&* z5MgXmpArx`6rjLbWss5%ws6Emz~B%9IWB13Zb?{W>!F9MwCfQB{f^6~?@1*n##(wM z0dF~pka^DlD|I-|gDR~ol(eTPW`D`=T++qbArv3AY^Uw<^B1rz&EeM-CzE84x|(*BcBOI zn*yK)`KLexFD}woH2s1+DGiL2WR4}WSBn6K%*G;ZMG?c|c#;EuilmtDLhTR6+=&A1 zb9bjzi{=h6;xTg#MV8l*^qwJ7*DQ7cme=Hz;WYYU{PZF_}0g%Z#)n)4|0 zTtnkC%*_L)X4hR9FKI@kJ4N{G-dlu>eSZqDA{-V;U_;9dMWVn~?VvlS`RwQk{{i^G z(Y>;heDOn}S`_$7*d0ZKLoLHz$7UfXX`cft@mcg+i9gNpUe2#VbFcs~0pP-ETma}) zldu*B1V?fdkMflOcmYidIMJ83vL>aOgHa7j@5l(TEVY*B^zwMK&usx&5VF{>6WSxE9pDK>TxJbi& z9E?k!tE|A?Uw<0HSKrBP73rjl@`XbY7w7iW05fmSD$u(2}IjuhCZp zv?B>UJ&2`le6M5pXoc+tbmMBo_BK@;|S67PuZb#KfL8SR%(b-bd$Qi4F)mG zKW57>J&ay3f@FQWD+kEHjab4y?GOw9()g!9j3c@i3qZ)jK^r2hLsw2(D>SBq07@An zU8f$Tq+1{yIqL>$vR(2;^-J)_*>bz-I7 zwutO_6!PPeNE~xksVRQRbT~sDXUZx^D>jq0D23sbf2;Nc`=cZ+Ndqqlpp<9vi(Se% z9}_ngvxDrL(lfs{Y+?TnTo#*(KfDqZJQU!dg)xS3#1JJcfehqCp9T419)^Jk_`D!f zFsfZCA8f;Rw@Dh62wbkBrsad%uzh-E8%iH>>EqZUP{9mAx*``X$`Lo>0W}?SrR@Lt zYkkCwHU%ek%-R;@qf*LK|CD5og|#H{7S_!2kTa!3QH;PQy(?N3i1d}(=(Q-Z?`GoF zLKDN;Pnwh>EcK>c`8jA@2F~PRuZ9Rj#T1KWc|{g(!-lr4&OnSgv-9c(E=)mBT`F|L z^tHMk&{2+9J!{?HWQ{GLgWuD3EKudGJAfLr5b%y$s{wGd>($K?#xay1G%4wp2&a`k zu75iP(NxU1r5*uX@w@P^r) z$zHvQPD?}XyJd(#(#A<*!p!+O_8nhD8cC&@HVy(O1u2+71{L7SY5<}GBSJeGKyiT= zW*&51Sn#p{h;UKPDsbt{y+AB7Z&^9Mk|3%I_QuWY>I!Aq_6@))C)4tM@Bre>~iCfU?iGfK67SJCO zK%wA31SdvYE|9SRyma$X5;bZG8HY82k90~1Vp<2!Z#4JHx0F8}BKTllc*>eLbW-?U z0{|@Iz@9K3Xi3)?=O6`4u2mGaHR>hq&BWOd0Rd^lOGVXk%1dwi%&G4{N?NkqSc)=( zOumvoN=g(~G%7gv37CC>W~FFRUdQNP37j;o3T9$$*#5meV5$o^!o#bQeM(StuL>@j zHiagLOav5#HI9Gp(n7a(;$et{m5U4p1Q?r^U48I0T>bFfu({a{i&(5w5>VOh_D2US zY23v0tC5%fM9q-LL2!C_$K^6&yaHdp3U`0?iM=L9DB^l9si*VrGk>V z?DL66QqQTlRaYCAxS6CAZy#V_g^phaCA_&;)RyGLVf&KA5i}-6qZ0PW#H;zD zWS^B5f*6L^A7vj%nV8xnmw0@|lcvJ}D^La}kOZ(2SAt_Lh@n}%^fJyLxk-qZzM1Cn%ds06677)_tDwvCv*?2?~15{9U zI0IC?_p57@bg%}`SfdT^Y4=l1zQv*bq~_%q;G|rcJmAuS7oZH_q-(5qd(^lGh zR-Ps^R|-&4vC-TME}(Gqyu!3}gS@wryICH=+pVP_16%@T2BG;JG%DVC;Y++gtD^a; zc&O(ZV8!gmK|YltV}6t#phVl`SUow-7m)IXfRvof5hZU#NgZDkr~0UksYgoUEXo~l z%+|{b-kNer&Y`AYCAUgk1TIP#1~|EX%cX*oM&_iF&AjXC_9{I2_*uAq|H*V;3f6AYoHUfZ2(RNf* ztYZF^{>GY>;y8~%NtZ9BIM>7b21bbUd~vW(=M$NqfiFt_7}ac3AbKOt_2Lmvy7PYw zu!1`9(tZuF9Q(d%V>}dmXope*CfP+W$;>NnjtYj{>N08+2^eSndU<D@$ zt9!ox{Y&nHSzaHn*_R}6N~bbCM=wR-Q$;o;y^-U<)^&U?pkv@}C^s+9Sk-yc@h=>! zI$mRaMQU*mV1=XPc!|8!cdCw~QL+>Xkd*rX$r>{=%K#;6L*nl-lYIWSnQ-MuUcLWG zALXm%RjDW515zAE$0bo*3N^=en$4bQToP?{C5Y_96JK3#!@ECu9@h$l(fdFi44Ql~BZ)CFM3KdjjwUw7=U61&B~l!X+XY zz-ABu43SDYH^W$j!8y3*y&X*!Y%mX}K}k8QFfpsXrmet>V*!V*KMR~FW3>8N0#Ilj z(tR4b1ibKg=vqRZ;kgP@(k*bFSWciHZc$nKrNTego(H6;<1i$>rDHY03_7xI?GMu^ zedG~tp=*gcY1Bxhu1X~jb(7AII93Ne^z_@aq1Gq|QotVt#nlHbN{TF#v?}}LuY!{} zzS-{sWR-_pDh;$S{wTw>6S&VprsP<;x4K9ql0(iFn#rC4E7{Zw`L=+c$~J`efBZb$ zKEFN5x`HpuuBd^QYFUz|29qf~`dI<$Bs0Hsa?}-=(4>G?q#F-S?1(@LfRex;{_*OTcr}$wgoP@cIY^*HncHI;N|21CGlBJ zlafxj6QtDJU9Q1MbrX}wuWJVE~4 zfF-vHT9f!Ygq(~`fa)I-gY_UK0+gafDUrUiMrGf^5m%@AmgErt4IU!vlcE69$>~ij z+}m3;i8utDaE|x!P+-3mhyoT@E;^)t@bRl3>uH+w*!Ds@yA2wXG9k3aESeR22vXL z7PWvtH&&tWR2!v137Al!pIa*n2;e$iAY--Z0aBoqfc|kE3uxR6K*{c9!%ybH5u|7W zCn4p69Vlb0%xFv`9yKqX7i<8CSftZ7=u?h$HG1SJBAv;0-GGl8450E@RBixSgz z7%fW8k5V1vo2ge#7VEt8?oIgU58g`&9q;=Gn}&h5Wmd~lK?@Pm=-j-5$$hWM zrT>W)`0~4O_culeVk8y$KuQ(`^GBbey`WC?*f*v8Uh}8mgpV}@G1A6xIa6@^wQn3@ ztY}q=l#27BP+t{>b@U5r01-s;RWYpVXOiw~Y;>)Ax>h^VX>3)MOevMdRK@};GnDPb zfCV4R2sU7vcg0XS+e3pt3UZ)F03>Nu_90{k`QCXRk~wC_`ph6NAZ0>ex~HP~%MJ-w zTxcX{Q{ta7=gM}w2|xJJyW!pUPh;k_WJ%(&17DVsM#8pjARWaunYqeK#(Al8|0}Tn z%{O8H^Dle@DME*qFC|@@^2rzfTm3#z*x?~_e915mj`L%buM#D!IL6cbDe=5!r+E~y ztA;-A^Sp>41@S(7{)fBZ0V+aU++x@EC&9|Vswc!W-=?2mDHaeM0!#>M&_K-$m?_tw zTR>KzSH@1;kN^QjI}*T|0XByM6q<7dx0m@XXi_v`voK-y2rd=+kqkforT;`gh0bje zP*EtC5c@0A60V|%dYTXQ)l-y}{o^MPoX-$&mBri?p zhf>NzR(VL`IQXKJ2w#br7i5G1Qn&ERd9=3X{Mg6C9#JBmB`R2)375_O=4Kau{FC>> zHIobF9A}@CNcIUOXEiP7IIqi?)>(o5FTV==fBwC{F)jN%itN?=QJS-SBH_q+KGEOe zAP;6>)v+Fd8Eo;pw;HDH^-A{6rCc@jf^75qY|d3P%|leL%_hW%UNt0fmx&%e zJLbV%K#E@uI){>+b|sGM>CHC$;UB#pc4uJfHN8%Sc_iSn%i5L;V3}UUM^)kOZ+;iT zmoNQu(m)DMjEIstR@1Md*2_L9#aSIi_qt0CRwS`wq@7!wHwEQV0gVYx3W;*0B)S^` z42TP$;i=l5Oqe@!FYdb?V|XC3-WkB+U|an+M2EN|ZKMal;JTi%`45d;QWN%5EvA53 zhjh0Dlu)4?nw0wX_TdI6WbQLskQso&&8J+GVfpdcX+85D0X)4XMFT16op2nv$DF{g zwNJ~N0=;qzJwmeDzVS)np#qg*{S8WHQ7adfbpWs_YN?PrXe%}O-(IlvNF#g|0jmlBNSjjg znV@jQByv{*7RdAqM+S>P2DB|T2MTCXO20|lf&dekr{(PPc><7$KK)V5eIalPE7FuD zqAN8cHb|`6v--3BOtQyT+%p*OS(z!P(3~aY$O{^{A$l|oxE=>Q+DR)km8~EoW+as# z8$e0Z8#F2GtwXDJETB>k{EXl{2~-ZzP8>pU=-f;IrmVMF*8o@&^@A=&z)7#DK#7H7 zEDf@JReEfYA!s~tfLRT`* z!`~}{l>6cpj-`Ani)2Qz54+7KeE-8I;p2~ckuA5S%;V*|>=wY9N8Fdj~3I zU?$i&GEg}+SdsRlQqu`)Hc@n-RASxsqSvHAmihP*F`FGEo8@A<1tEwd7|Fjw-jkd! zrHkYRS{0P&5t2Y=xfbPBrNEY3ze$GmHpo)vHpks|6Fz)?9e(uDI}g+B%ekOQ-i%K8 zQOi=aEzYW!Vh>;irkv&-ASIDA)-R$x3e4UAMF*g0rU z3!(uUNkdaah_2Tu4T}fBlukqtfd-*zU#7qWTF`0mA_0`7Ntp#HMVMmul{?*>u*C^n z-7^Q|_Xu%fKVHz}xWOKZ)Tka>HcudRvdYvB$)rM#dCrVqT2Dm27dzM2HJT)mlf{Q6 z7vNLw6@Og>?&V}^ zP8xhEcElC9x!Q*Be{dU~zk8j)N(3*DO}j#u4}4iJreQ}sSSMi{v_bTfma5N zOfL1jbaAP1j1{=rZNihAUHNYtuCKS@`YQjo+if4Ej|Z5BZMOT6ve++3DtU~(xU}h9 zftYFjr=N!K`&Z5isMrKZfdGd%1Tg@S>T6Qkiw^QQx>rr|82wPd3BE=HD;g6NEetd! zEd+7Vj&xy&iw{ciqiG};g)Juh#|uKta)|d@tj#M5X`9FPp>%AGY5t(h)lfmk0iXoQ z_-#OnSrs0&1WY$Apdul(Z1UId=+@hqKV)|Vpp zumVwFkAc5pR{HpF^kIowmYeHs`Y(c(2x@i-z-+>Hx6K-ul7;&ohP+CbT~f*2KI|Sx zT!B^A<}4fe>Seh5htETJ*?m%R4;5=nK$uBl0XD6|{wdf53xGwWy#<))A&9fHd@=&r2??}#>Mml@r(!~e z`opUop>rJSIYCJWB8ETsbW>|;Sfp`l+7UWT3Sbril%?Rs0Z`I-D@c(}uvfsxJ1^c) z=7kDW6yTu&6_Y}g%AU;abzK}|pZTOg%bI|VQX(gam>IuBajm^osow-x@lesFV8zpR zDFZ9(11TA3)Ep_rq$>fCn8>mCp(G#^LWtiYp*#gCd(oWl0#e)((E}`)WFsa)WPDbF zXr+%>DM4iXcN4(^obk6+H&5}}n?1Ej>}xI8H|iDT2a6p&JZ2qbrGrd?1LB6%e$ z3z`}fg{(Txcj5>*`sayySU=0+74|q=o*urT{)EWjImoBNCMKxx43?CUG#L!mU|ZL; zCR`hfv@8c`PlhpQ=3k}oSppOnNYRA5ncOL}!ZKIh6yyz1!-5wF_?Q{Hhg!k0UmK{X zd!@W|fx211i0`(eu25X0KZk%7cKsWtkw6Ogk7V!?fl2l|f#_b~pOUmF5tI~=k`p>+ zkkTb{jEoR34g4W-7yNt@`z@g3mntV-0UW+Kfs&$O#{dR^OM17DWmP!A`2YYQ07*na zRPuM-3}QmqKG}uc)2muHftpyRXl$a^rUIDqdjvAkKPG8t(ti;#l;4vl{L*if%N8)D zz}V!ZlKJ;bsN-cTxk9bGec1o^FT(zJ3;a=_d%@(Z%Q+%yQjmi^j`RiLg^`A(^GzwC zhO47}stXAs$?pi5WG2Y94b{>AYofnF3sChNFlvsSQ(6DlP)mpN{p#S z_R3*~amM+S3#FKPMJ5*$I08tare5)RhdWqJim=`bmT*m`b7||iE094*7MEDC5<=Kv z?aMyrXt{dtCPb|Yu9tyIeh+Q6XDzo&(%M99QjCiea7hSg6ZTiz5N>uMT6TS#V$UTD$h% zxmLrz2!or!7T&T;01E?BqH{dBY++4GGTGYaFvBU*SBlzI{8Fgqr1-78in&vYA4&=9sTvei51!S!xXlP) zNn<%JR#KdBuSH1}h?~Hkiz*d5{S*m;z=Ua=MoQlYs;|z|kVjN$E%g76SO- z<|G0Tp^w@$qd_?s*hm1SnR^jQTNTg+dUXLRqs^|DLa{(+C9q=d|UdcXk{A z&Zy?%pdQdd@IVbeT($y(lx*77KuTm{)!eIql;;q2H{%g zOQF?QAcF)8tn90+$o0JhJIpHfO`;VXJS#TiRd(D4)MLZ1xnSAVI47t3a9V-<$)bnpPDM zQb7uU3Y1wMM*)jKCfCi5^Eet<11aT1SFKGmFH68A5!vQ{(r7L+_cFfO4Rl)g?qmUl zY4$qtEm7KFmB%b#KwOns5Rt|zR9e&)*W5(=8mO^=09|)neyFQ~gN`8E+37`)Bbaw# zfHGS*^N2h^wypwDQl0EL&j_B}Y0?hmjDJdPXI4OV2((^cAl`WA%}&J}J-?wy;kzdBL)uEJmwaM@*T%L#DO zIUkq9#`f|q-2J!T9BxKC15&`W3L<2&RI#_GB#|gHF9BN7Mm)ev-j|NP* zG0y-Q4>%e6&_Do8PV+A*4T_-3YJaKkiUCkco)ijF(D8Q*sAUz_04k0FTV5@)=Ft01(GYEG7v&Ikw5}cdVo^283mYR(9!apG)MZVkwN)Wz?>|SU)+8< zn7x)IpXh4tRq3+gIIjQ|mYo_RjRtPq?3vr2NtS*1K{$O2EU7W*&sx9)VFQ*hiW&*L zOj_;{)PdR70uWJY`8@)ZG=@==0yAHbJ0;y1K{8YUk8!Kfkn*ob1}Zb!2uZl7^YsF! zVXkGqn!xP^TN*{{-c3+1i-NlQln9t(uRXNS16Wv)l22RBkpdtknR*pXN^+JjPW07r z9wK?=s9s|t#|(BZAjPwJmonT6B&|jXOPu^PVpOjytVwA=2F$+zlz^rr1@S^{R1Hdb zK59>LRI&Vp3*n8*1pAAInP)Nwi#{y3SK;pV>Lli19ltLwGs!%xL=6MrayemS1!7dM zfA~D?KReLWt4ca8YF6qAX({UOB*IrBkC2HTJI&YM2}ntrlIDlfr7*CZWj?=$d??ZU3&IX3|CAbjI45+Bnv|R~rO&J41}S9PQvTK1XN!UNV zzPAm?k;_83`tDWO?%#yX^P7_cr+b^c)$up4!rk9}9>R-AwGRA2l1HW73`l_}V4z7! zBu@b;$u}jw$C>4a(8QxJN;MBF(Y}&T6?WK1VTf~FlRm;1kYWf`%(83DrDjC~ropA4 zg|ZF0lP-2EO^`VjQ|&p9m4PjC3$8-GqC-;-kO9-6-~dlg6xM}8xV$u`*)rWY1#r?W z=K}2u1{tdWl=LA^1S#csPYI-D8D@YA2Rf`vaRDmw^%nQ*5WsOrU4cwm)XaLHR$vkU zX+&|rJqVSIZ3SjfWlMp_<4V(9F5|9eJk}u}%IZAoAKlvu?fBt0-S9s`;0#Z_6V1I|5 z=BrkvnQvjh0uj8xDLw&>cDF;%};jlmob(GJ5gn|!h`UM&18IXeOm*`&=n1G2F3Qe5Q4>xSK{pzO zlzjF}a!l&NK zMmN{nuz7No=3X@+#n%KtM>hA$AOo9(?Mis#9-Q=G1V{hMeKcbi(6|iD3;V2~U6H;5 z#^jL^1l&EpO@QT8KbzNg;p%6<3!4|O_%0)8il8L|ly|Sg=EEmp^TF-o1uQXv<6nKU zj;U97C~!PD`kDZO?Dx~95@%81Io~--Wxs`EuV|FidQO|tDcdRS)FK7CGi&uA>! z@`L>U|BfFV;Ri+7mMujnJl4!~&y4zV_NCH+8wrvi0dTF%s$ILP^(_!OHS@4%FwVROSp>oUPl(u0ItU ziYXB3Hx`Gl$7gsyDPTP|NjJa=PCM0(nM{YkhpMFKqX9@SOY?oh|D-Q(4POI}Vjx8= zix2?lW=ZyXQB=7fR@(x2m@D%npt9OEqHS3z{^34%G*@pod9-E4-7QZ5F3TNV%~P(5 z{voIN0#X{E6p88uSHU<>%I$?LDe#?rQndfcSN31|dL_$>B!ARXqaIX^AnHWy*VNo# zmE8M3$lpN^fImw0hD01zqaiYh_5i~2CoGB`EeNFyI(ZO(L z>TLEnkvSZ(a_kqm>ao>Ba(bgrt?aSBqIcDd+0+QAMSW3ERY=XkC^HW|Br1)viUN{; zZ_}b21}2L66fAUWDFRMrGB*Ig=u-_)mOyL+p!DF!J~P^bWVEELRze%2wQZg^5i>yL z&`%426*=1p`ZlcElu_unfJ!$IOIh?#1b$+lf}R7QU^QlSS6^>4(>5*|@69`_Myt#r zkiyr!Zj{UsKuGmLxm+NbBj!m_Af*KM)b*OEh3A1WH+Pzz*yle;zn30>091do4&@7n z!xO*&^i#RdcR#Yx;UOK1fsEOC}#pf8|^!{wOJ1t+|D zx_l@6^xi9b&a%z`0GR@qNk4=DO2-t>lEISVDwK^j7oYK4{wdaSkF3z|7^n8*SxO3ZT(SZ2X48_rJU+(xZ)b7m_QAK5lQyQOl`2zW{uEiO$8>zKz|?Kbq@L9 z#QiUyG4T+BCdj_{cfVY&|Ksm27q|wN(NGp6{qzrix_tUCCoAW(LHPO8<%-wBC~_D^ z5c}o%ZdRi31V1x@qps8fDa}Ms774l5Rjzs|%ZlVf;p<@aik6DtCD*-xrq7weR+=Wu ze5nrr2MMY(-s7>L084u`by?>F0A%%B-t@OaM^DHQ7lzF4! zQ#m5wV6rBxy|Sq~%G-0E=f+LJ#o~SG7f+Ux07}y*Q;@P$`ZmH6Bfq5Ls()GTC(Lq1 zcQ4)5-!*pnGl(&3?_p6f`#u0xhITFhrL*ysmhJ+UrVY;a71`aEH0SXrP6kNft6h-! z6u<{X`l5(k6pol2=@FzzBrkRKs}Da6*S@$a{ZCyZO_PlE_5o6&XXm@8Bd7UTXj}mp z2u#pQqO#H#U{WK1$zf3(>5W8=7U<{?dr?DsP}2LkNI6y)FPA@myWIZ#r2{s%%k`({ z%k|&=?sEB`|K=2{%F{pn`SR)i`NL!93L-&{8U|zdcRyb)|Lzw8ExTITkrw><>*eJ? z{?q01mlF~=P86~R%9hEH1SzmX7cf$zcmbFYpA@vV07wxl35T^V$sbkpFtWPTcy(wU z(N6K&Kc(5WD}Wk~(}RFzrhfIu!fd#=fs1CCRM(D7y=+-`dAJ1r5?ivEDC5$O6*yXg z1cSj$4t%}<4b2|xIoNN4kG>A8{YCy2fLXkoTT+%v>_YkV6wdDzsLXZ^d>+`5yj|=l zkeZIyTLCJo4r~>6cf&dYSZ4jybkiP4q3B*8AjKWO4}w#B;0b<}hwDSZKLIMJBQsFZ zzA5P>&xZx^2fj86*Y0P7a5?bC?i~>`d|JI{XdT6 zS9$u!KV3fk=Lc9)B4hNMXZB_Jg>tl@kIVh9hTZ<*FPGc@`A4)`o%*LH#1f=1UCo=K z!wxIIktj%!@WKpU@B|VdV}TU$Ln)wzdqG=LK*n-bj38w=)@=L989; z=`%UWuPiA&ND*HY^he?7Uz9tAd{pqS$B;6QtdmPUTP>ke6^svNZ@UK|iR16`SA{H~ zLf}N@Sz#bRfS~n5X)GW-88yhz=h6(ckPKtK6_M@s=dbvyexc*}KY%6pmHglSj;??K zSlRe{Qa&l3BD2AMzsOI|^-36kQApVN+fRo8nJEk;aQsjIa=HD#f7+LIR?-700^3#CPXWW@ISB^qeWf11;~&lWWh$3Uhk(N>xm;X zzK(#W34m$jUjdY^p;>@}V&4Ap1@x}<-}L<*u61p*{xbi=gc+@L3|C8Yr=G6e7S-zin?M} zKn*+e3qR!Z{6s+I-~Ua@vIIPy|H~gQ;Fq#gI$nEb$X-PQ%Qpky(tV{?vv`>o8m%<^7b*N!-d}nKjMEB|)=T)d-0xWeBpqG?h zPZ4)n<7}NBSG%C)-p6aBUcJJaa6yG3Q>e^Bq3&5u`AwAiZt7Ha83454-SCgd5Tvo% zS)O?yX9Zrm4jI6U+K7*X6l2kal*KJ;%A~TDQhEkZv8r9x*}Zh-3+`M4pCAC6?OGwZ z7Q0Y(3@uhG@HMMC3__SegucNBFHH#IGeHViR4@dwmPzBr4@=4`9DCnymFS!CbIc!Q z)=B{-+FH_F_i8|b=xG(q6rjKr2tTdx%ONziobY-OKy>-cz9?|ji?B`sPvmJJPW|@Yfc{ksT#1rwJ^B)7iqVa`=38wUjFxg zxKB$u#lBRcpL2*|JgOF!l#;(hInif8N{t96ekaQ5e&#sO$OO-UW>qG;atT3=zlCjyfh5HV$O07n#bMCrO|YhHWn!N(3j@c>Nty=oYN zloimB**KlGjdnNA-HbA?OD|V!aD_Lr2Nn9&itek;wC${&YXwxiah$a+B-r`2-ql!Au6*UII@lNS8j!-ZT4SZB@I6nF zBPY;D*@yN3I?Y42^Ar9?uwqzMRA}G|Mn=G*56=ov`p8}j{(t&%xqSJiz)1^M#E~EB zLCa2K{edW8*UJ?$*8khzUM_$8^D=VQ^}qjmdH%ouaJhadmoS^&3@bb*jKLum08W1Q z6FJ_4FAF4X{%jPKPBfTe71PHOE#$m5G9l^l_dzOA@4qrgElmYJDa^iQdCZc@~z0Y1s{M zvXVn9{j+|^f{!JiMgQR|?|nz3$$KDG_VfZ$nw2w|A|F6y5dhujvoriuX5(@iSWy*t zJCOGtSuKbn<#jhkcV%n3X6kD2D}5;-g_AGBAvFgnFW{8Ai{ zB7OJ)QZnb%k4byIUY;OyZNh0j(oq6F#(yVZqysMc9HN6~1S91D>cItk{{~mRzL3K_ z=5NuKlnPd=<)^Gr% zdmQ>6bjj6sN4<3&hKtcIV1u2V#GWC1$Jbk=qsCLl10V@5NU$2+z-$GK!U+9V$gspyly4?QTpD(xn>z_AfNU+EmAccKSOpwC) zP|(Lj=Tb4k6l@RmYA(dlpbxwfVgR6|?Q!Xm11Z-plZwX<1pxo89TO`~i?czvs}h9h_8tN z7P;<4nde^tq`>aLk#6v+wcPohffPKMseSl=lnCbI?+y0=CUFEy$^-s-Fe1}P1C|Oz zNT5Q)^GNd`5K%2G1ylg-zy5lG@WbL`QnTJOP~j_H`aMo}i56z~(4a&91XPin72rsB zdPjUxW6p|>AS`>%N(Y~OUZa@yHT;LRD7J3tg5F&jUWOE7AhN?+u+*5|cDJiH^2BGwZJr1V|0V@biQ*PIv*ekCn>)5HJ(AOJ~3K~xrCV(l&~ zWkmV{+KOSx;9vC0`S^QdJpcd&fXZw9wIHQRU_I}h4R*5%ii%jK_>yb*zi zN;oOsg`Z_bA+SP|SinuGkAa8=OZ8nn{IpfYTRuCA(rb*@tJawWDJ79&6M2gr>iNf( z#v&q?6dm2m$fbfuP@$14UM)yzEGbG;gBgXhO0@+cb`z4Adf7eFJ0kC-S{>`tQRN(SSle!x?f3e6sQb4&!d6LWb3oK%Tv}vJ7{7&qq}6kOL&0g$j+GEkrN=L zfD^gu#s9)8!l+&Hy$31alfsVlFE_HTG&c{m%u$d62R5Y0fY7Tu5q+Y^%FE?)`}*y2 z!>!`O!V>Mad(%Dr{*^M58x7OoL?2lF^CmJE^Qo4S%jNQ?FPH1L7j~E@ON;oVl!#*- zez^Bn!S`%MDOQy(GMElwtiehvX9YRBsVhM80ag~X{Q)3FEF(Hkid^TCEc1AZYLFsX z<`HN>_+py51V+?VF8Iv*bL%Ky(|B7zB7D>eZ)d|e1FTFmiEXR-kz;yif81VYMnR9) z^8F4l=`{Hne+wwMdk+)1JQsAk;NzYE1$h%lF{W;0_DyM=RkvKdi^qs3nc75RZh!fDd3w>{ zL|q9(08)KZU>WEuUK*HGD+}}DxhlW}>s~ti*E4MS3*Z8Qj<`kSZA^*4|4M@b8}C?Fs~4%rGC zF6hX9`IW)|ll6oENsaEs-;1?GTTWW=(q9Q9o^2E`lHpcD7;BkYg=O?taTOZw15c4T zvv1!luOvtz3kZ)6P7s|P-uSGpduhjcw5oIJITqES>}@R_)R!0g1FH3rsBfm3)H& z@9ed@p;ntM;L+E=OJf3{5yCxuofdzpS0Vj}|{)&L+ zD~B1TM2#xzJm*WPc~i)uBDq(lAVsc&!77Dc&3}4EZEdwwLmU6eL;zB5pI`15zVu{y z-wV5^-+g+0uzIjF8-M}}3!-{`1JE#9Pk^?+_NDz*$Z}#k)@$DtZ9(blmjiS5ujO1H zQg|Xt(ZRla)5Vh@rCL>L&XUo3!Z1`>Ql=q@@hVsKJ)tXMeDzBJkkIge-Z*j>9)FTt zQVll!jx@RMr3NFbDh$VM@;5xw%UCp%RHq#zg}JYS-Ep+%(wDVXe$9OX;C zl;TJa?-WQudDZe0Iq=^bUFQPpiOPfV)$1h49EQv6Beodzj*g-revXMFKVAwdCq(9EO1HXJcOlh|}X##6#O z+WNiQqaTj5qiyHmhGl>5!2(-gOju9dwFJjEpXKDJrSBx zW&vVW;KST6xqvQr4oDeRlb%-23iejP!!0UZV_p-eEc;b<&;?NltW3&#<6;&I?$-UT z6RB$`vr}kdPp!dL5~B1s(Kxm*Vm;6n6Vj<0eF9|0jv5=iA(FNdxU zZ9F@?l?sc^x(8tC`^!^icIMJU%6K4!EfvKnU3^g(Tu=vhmJjqX;VW7?QDYODxMrLO z=lQ}za;XRaDUS11L(*5dTEJ3!O#7rXr%~V-%+f~yNA^UV(q|bhCQ+8v>2us*xKqar zko5b*tSc;~ePzIpbjoz3qqGsMtV zu#4n*15yM`@CbozdQFqDNz4)ZywJuUk$j9V%`HFrkolgqWp-&2jB^C#J3O7Ub;q_(+ zC5+0aTITrr`vNK0pby9T`yA4cW&WLA^}4}a0e=+Zud$*i-~uZ|TT%+3F`Vkb=G0nI z_!^lCR}5dEkrfRm=K2tbL@be%Q@I;!&Nep-A|%o(|%ur4R7vtqr8 zp0%hn`dzXuS)ei~{9S!k+jiT#1USyt5-Pjk;mJJogI;Evpe40i26n-I9<4wM;|MsA zv`>mSzZZ~lQy@kAq=Z1q^#akF%&1)}kh1LSKtJ4@1P=3Wbd6`3;q2aWyd(a2)$2Qq z>b2BweuW%7^C)oy+sUd?qkU;7`SG*9@`dFCNg+W-?XRMLE|3Eh^Sl_Li*@^YWvBf< zZlJTPVy=RcnAb;?w?s8IsRdFRjfB3?b+6Wvf)TgyvC3n@R+VB&(T?!t8rbFX0+y5} z>@e}_bE!zZHLBQ!EHC`mJI>1p-pg@*rAkDO-|2CgRDlkU`x|61T?gt#cCA>TfoJlv z2P^=ws=KGp(25|_y=ehFN?Rf{T}8{ikY9QMnfBo&J$L7X4EV07?tdM{G8j21_U_*x`ZbKC7D_|1otI1ejKu)!! zuo_#k+Y2xeYl!4hk=0rMWlseKSS-b4rbu|e1$jC9+#zM^-s7tIKN_T<|4EJLMTr{a zdYH1T;9yJAMyBCG6h9Ogf@yRw$*IEQ`cdhWqvo}@vWx}QvUjppd;HG^Dl2(s{g6`hUlXV- z8h4}(?ii~PpVp&Zcw@fWHI9_++JP`YLIiUpFG;cvzys~eL7yfPx=O*MmnE{mHheOd&Vh?S%|*3;%d;D|b1XzS;yq3Uyd`Riaeesi#) zUAEhxA1i?qEY-)I0mUs?1%$X{ZO_%P0Vzfq^j}dR z1!qLD+NkJW;qFGb{vB;1T>+GtSeG zz4(lMP(a@XH3FRGfewOsBY-KsCv*i2=!#E@fEu)*Jkw!a>ernjFW{7{&m%*z)lZKo z1pNh3oIVmjZuR!{muK`_dQX28WPuVmX8sVA7=T2c*9c%0kk}Ex=!zFA5hWyXb;Q@Y zbZ=eJibo4jMsQ&%7a@hC>y%oi?gU37i#-IWL_i9H0R}0`alKr@VxTcZ`2tX*!w?sX ziOP*4RuxXZ*jQEYmmvS71c1c~5FfG55+xlzClmx3n6OrXU~+JQUp$P^d;l=pr=D-a56UoV5x( zW%L86jC0-F01jONgX%WGj#*@bPv6>QTLYlZ+bJUTWkCu86|jmhNa62ckOCth0HqlY zzdtj>knNgB(W7Gee}i5d3fULU(zRilq+6j zd7)b6s+a{<^p!6-U<+8`wM)K)idxKm*2GAQQ0jJmjxaoM2MFQQamLp zGHc&EQ1Nz?ogKvM*Lwk#bXz6`Jo)=wF$z{Z`J%h6rjxqMEkugq1&=LD3Otvv!)Qs# zf|O5BbWjd5{1_kwhw$4+ruxiOeUA?Fu*hzI{dR%qUPu0-PW5BxV!k@2a;r#=6ag;+ zO7P##VP0raF;God0~Ts&69G)^Y2IPKdT&J)^Y~f)9#zP~W3~ZOu!peI^}lVd6S{jR z;f2Yuo-8k7MPYCP`;D@;)H0PGhd@X7l51y{Pl^B!p`Ua_nG(t0+D->7#+i9+#rY$D zl>g~-uoKzj-#yI85LNK|p0mn%^>)jtu(ZnIGvmc{Us&{k1t=``TXbB=Y(og7e9u5- zrqo(Hh^4q%>v2}rTbZ-nXQg<%JblG>x}|u1-~j>;eD)Q4ZAsI2472>DzTpsYKnh3f zf@@xM-Ah6c(^W9M?#0)@z)uAM4POWQ_I$m(JU`KWXe}>(UNk@s#^rqU50AG*fuU!? zA7LKY=`D%-da{7t_4E6?>V>F#Glrv z@PltUV?7<%v``zM(k<($GBGGp>uX~k0MVeux)SCoLn2O;ZaQXn1}PeV+*EFq!D6D5 zKI-I-3J8^5SOE}iF)0Zr%S@nFM~~@uEFZ>p^nU(%{c0T*p)&3Kq9Qp<3IP-FKXE_`SX_R3x_pCQ z|N0XqI2X+(Mce7^zOV5fELOjMz1%(=>gPJ%Ghg+3jq$l-op9w3!&9I5M~9k<`lY@L zASsUVOs7GNfRSoRso{-56Rn`60*KMVQXA9&g>GB)K}Op#)-^MsXh4xFR-ZF?GWLoL z2+7bEF_s{OUv@qzrX{8Lj7YRD2~8}SVwmrGF5cTjM* z@pgvYD`3s|ZGgS$F6zAS+Ot~sp|S>%Rc<&eVju)255oax z2YUWok3|JFix0izZ|ORSyEn2eTdG5(oT+XFRS0i5-TGaEv4&_7cOK1zUliQsX_gBp z^u34?1%C-n3_+G_)}haUo-N>^3eEN)Y;Rrm=BVl|BL`B3)v>WM-ZW5|psmO%Lz-lN z419y-L-K5buCoBk61XlJ5NX>M2(}81p|EKf3Ae+4=##>^2qn4~JeRP;8l;e)$^@i5 zUoYRDp6DvrRi%Yk&4C^~u|jgBi@ZbXHQ!@Cm0$Cbo?cVtd)Iw^r&bi`x0gSCxp()q z5y0500tX;kQ*KUApw|`NJXZ_f z<}v1O@qv%3%h*`5O5RMd(OOAUjf7uU5xvCM1nDF>V@cp>gdr{8TUTBl*BeeAIcAor}>X&F3s} z$ke+FN``s@fG7hv8vYLNEpVbLSnWB+(iw)S0Vu_ilAXO}RvObYGGmuC{BlMU;_nc- zye9-+-LrmKmD}CjJXu)THWzBB>~i~S*?Rn@?-vC-2h#dMr!ACqE9 z;p<)nq(I~^u$a71?iBotRuu79;e$@<4V+L&vH?<{TxOHa(np6OO84PV-}cnIOWw%M zLw}@`{87BQg*j1p?NorWvZjz_1$E?7PJxoaiN3y@TT*C|55F$*+D`))!-7(Iv{%uj ze`ddI*5@qaWY5g(BU;gDRJ|I_mph~Wq*{DG5CyWOLR(4L>VaX1`{%_mURzbji5{`mb;{~EPaZ|--#pzD+YlfklefOUr}yR@HXd%x zbz`AL_>60%_UNqqtc*n;-UeJ{S zS|p+ue3vU;U}+J*l&=6tUN}Dr0F)=X7AE;p<~}LZ5J@UIG^>*p*0XMoEdIWU)}|2Y zR?RQ6;bw+mN(%}s<{Zt^)=k+(7OXrl1eLGAZZ8f90+kq9%vw}M8#L9yDvi!%E zm+@Iu!+Xbhodj~!VRFDl)}OAUk1AGaM5Y#a=ruh5+-@?iqO_V;e1prhq#)y}kyMZ( zQM{_vMDn8`VCX@L0w6tjX`_899~Oz)#o&a*sM+VSjxu2F)h>K49`u?{^@F*$4(H5z zJq|pQQ6@$_Av+J|6#@DdbT;%ewgGipG=G11c*yX(zJ#!mW3*t%=`tN=7HRywB%Fo-j`>9~FGA zu7SaK`48wtr7q7EXwmO%Yf3HO=>bmoVr3Okd&D%Vm}6m~Lw}yv#a2q{4wH@&Rv2Cd z2PoxVdW|~T1u4q;-SR_`(8D!n3a9BT{wdX01zS{-Jjy@|7$Kp7rpblEfTS78ZbP+B ztm!E>oIC!GygGg($L*|!h>V_eN9y-@htHM;VVFlJj9Kmhprqd?BB6xUiW;s^xIm&^ zj!iENWeqSf$lE5U{B@{)iSrFz76Br0GY^!FKvm?P7hDXP#+lnY&+jF z{q@uJa{c+!TNd$J@;I^PKopFe5%J`n@b_SqFMO zG*0*W*U~B27^8~yd<)OWm9QXSsWP*QZmh?(GDmM!^7i%`l?DX8&xo>~l&D{wA4PMa3De+c0w94l>Rc$?KzQ6l_L7O{fQ|?dh;DNOUH2f$ zXSIexJVHcAR%%x^aF_&0T!CgvxfG1n(a=o_x!}PdSe6OUuhwe+E(%a)JeS}^HcHWf zjFGWH3h8O_zm>uo;j^TfC~FfX(-iu(fJ)Pk$z8>t6D?IL-rDL0^RMQRP7AgLCe^>JS9*r)Vsd!%x)<<7JiRc;ZB7?cR>|w4wwpm#LxBk8V6ikb zwnh*}U;=EEx>6+(y#y?1kWxNV6fcSLHGq`PXN7X6uq8#n2!|rZrk5Nl+)Fwnvh2AE zq?8cF))Jj;-LA?KJl?H6VRm$w$MnHXC3>tLti~;V_U?EWVA3ysV=d{1dZ6Z!;A9Y8 zRlW;k`u#2vx@>BZ%LdEr11D=LCOmNlxqbk=#Qc-DO(_gWr=p1yVKu^05&m^@hC_^5h3v(ME?2# zfC?sV{3I88?leHJ$ri>EK#I5TJXl7Ur}`S000M1s0g)u?m*iWK!@T;RRAAC8{9|VN z7Q_fW{=3R>&la3gH}6{o#5C3&vGj0Vr(0Mm-)6{qe-swB>?b#94C!%8X%f*vN)4%oej zS@7cl3z2=s*DLRq>j;)WMt7w8jlg)^c6pR`LTC0tkai7HGArYU0V<15@m6|yzwwjF zz&pXilS^jM8BX>?_XH~sl9iPcrVkJ*k^!Xf^(yT&AF`x?UJX~h;ELDGlG2MdTSEq2 zpjG3(-lGQiu6H!~uAlcbWv)!jAWW}8N-s#WiRwB<8R;7*1;kGUA`)zMz!^u~eR<$D zuit#C<6`x{9>>}E%*3?Dwtv>2DE%1e_mR2MYeU~|mzU39-|QHog`$fFhEtQ1KeoW2 zy*AdoYrp^vS_4A3UwY?y%bKD=OXbl<71N0(iySMk!h3ZAHiN}y9n!c5U^1Wuh!rKI zQ}oOHq34JLI!g*Uu7gRD!vpKj;!7gsx+`79&?Q?pI5Hc(>R`zt=5x2{KLqC3+o~{#;b*f((2})?I07PQ2mom^~w(K zjRLRLH=&);YalZTk~LMP%FO$X-f*521yJC*Wl14Flxy)(`3A`yB?K|#MnV6S_PUo` z{h|YJ*5=OnBzj1t`eC`6@Ah(ehy-da*T3G_FYy7<*Cf~L<>}|=_j}DtTL10k^70uh zDTjOPt_(1ba4wXWju-h&iK&?t!-OOi$- z8ko*F&sWL{FwqGeMMfnzb-}oUSyOpBz1545s?pE#TQp7bI?kU*^CE1%L}#R5(ux=UHh$iZ$;wL3DT{ zZS~grgWm5R7Bnqym&-c~Q;gTVp5O5`FP>KjG6AG~M}I|GSC$C@2BKJir9~?lmclRl zXY<{81P{RG^|PEZsYC`4%vvqlCpm8^^3GbW4i+Lm?CRSQVBQqyTlX zs;Dbjt-lHN0{NK0zibT=OG$4%5x*8~ZRxYj>qL?)odBcK3KkmA0_&&XBfuk2)>Vr( zRf)(FOdl!f0uw2c2Sk#5+VqveZWUV98wEBNkLKAOfQjC7O1l<-BLifFUmBb!q00V= zAmwaj^i(C@nic_|5?R%r0>0wmwJ}t`Zd+6fm6Lw9#u9v@o5_)W3W*sNL^0baGKivi zBtQy~0!R^1LLh~sdx_r(SWy6+aHKB{Qh*-(Q^fbB$kn%L0aBLJ>x{mMoL)g1*lawJ z^ahB^N|5*M3x~4xDhTp>EwbxRPnYXY&#zVeL+gbg2rzEn>mP!Fg~g=I-Ht{p1(k*X zhrHACz5p4OP*T(BD`}R+M1Ym%(_3GVU&4Q-0&oRnGnv(d*DRxBTHE}0Y}e&2b?rKy1igIt_Cex zQpy5zrdwtPWRSxJ&7JO#aCoDk3BHWq>e1GIY~W zCdnj8Zf;`CgZ?2i2{aeJ>uX;68D8sRYYT-WCQAueP#}3DMfwtJ3RzO*dKf$hdrdQa ztafOE==386``4iJJuGH z3*<;)B-AYMYxPT)h+bV7VC_rN=0*`q3jd1&k%dM4OzLL^X3)2#=05@2>X%Y|R7lKL z%Y$dlbAIg|!L#jnx=ly-c~M~^>nN!bL|A^WG}Ch+a6p8CNjH6TU+sbutDM)C{{1QR zQP8mfNzxxZAT!&T0x7&fh9_rP7?b4~QKnp)M!U2{b9o$8z`b@x`)$Q1)P}zK8#_~^ z9;xPDpvCO3j9^_qM2hwxg{Q<6q)3!5yzWI==gW03wxVE$c?K?D(RxB5i^alHK#H_? zdYajDeAz6m49p07WDs81_a_9=Qh)^jrnMST^BWX%xoV4vO6-Wwb&eBsg1^-3USd_j4(+djJrS*Px-S{% zML4$FkQIeSrC3d5O@he93RKl7%aRfS9;@9cQa-ItM7D~BP~XdL>S7F+fI2EdHqa~z zg@Mh4Fbqzj;6diYf_~M$S$lfG;q_&q_vCIs3eNt(lnjuRb>S)S5ne9M8vrWJ&T(MH zpAJ+eTbkFW-g~|AojqszO?8kZBiv$#)@;;gwr>oU6d;i(U)m>ytSRI$j~10rPt`X? zu6y0CmoEyW$aS${xUHtuxR*_1A|R!?1Foln-ce5K&d6C9q0s=vQv!$gFa~gy2nOYi zwQG>|2@*E`SO5j5pd{#wOon$tqn8^3he;B}qAQECG;z`=U{MoIB7oreuKiemjsT4U zCA<<6$}_k(d%?>Hv-?Aft7qw*XPgTMSNGe|gqB&4g`b}YI4EF( z-;3`_jSSWR6CD|>01|a2Ogs0pfX!7ejZAn@%`JO2Z<}*wKDi@%yOfS@b5XkZAyX;0 zcqi6&1UM9SDdHF?k@?<;{1$*oCs+v3D59R;Y|?^W`Xd8SqTrDIDomJI@!8!hogtqF{ut z8)hxWt6q|QzF1SPm#?=QWuj+CdICCJ@dPlDenBtseC+5-G)!S5JHVt%%uVQo?hB6I zX=L6x1XsXr-@cJ4>n;94sNtV}Jb;4p_y+_jt0`D~Qq)xK!3xfI1z4K*{9J%WwSu(3 zgaC#0OcXT*dMv98%UAQm)MSye9!0L}Rj$CnRj&@DASS4r8CVg;9|ZX{+2I*p!HWV? z#A4Dr%`4DSoa;4^A+?9Df$?W8oC<@CEmMtxrc?8EHpty6gQ+EV0uQD^0|;9)8Uzp&n~>Ik)K!CTsy1t_@U21`mt;ml0X zGk}V#;GVVW4_cI(ewlPqr0+aF5gulrZORm_FEfYSF->e>k<(zt&H^dw%9oWV1&UB~ zFS^2oAO!&mft3Eb*SE{9iS`Bb4d#$9@UPkxt}h&b543~e6em>EAEKayfSLkFaQ#

$g@^ZO=qqcIr(_ND}uv~$H1emDtC;BB= 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�iYq_Zd1CO3tdHDtGI+&mYU1MC-te15b>#vCx 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 z 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 literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xxhdpi/version_top_bg.png b/mylibrary/src/main/res/drawable-xxhdpi/version_top_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..8312c7c77431c4f437b5e47ba23ef81dba40bac0 GIT binary patch literal 126943 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 V8}|9kK^EZe`W4g5Xnn`n{{yM3a9scZ literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xxxhdpi/left.png b/mylibrary/src/main/res/drawable-xxxhdpi/left.png new file mode 100644 index 0000000000000000000000000000000000000000..7e9f9c54f8bba591aeef2853cffbbb8f70e2a67f GIT binary patch literal 1149 zcmV-@1cLjCP)<|KJ{BI?Y=JE*U|s~eSF>B|JVJyuHWJFz5ZgBm1dcj(SmIs4{QO> z1ik>Smh?o^0U9OP_KCpjz=1mf4J?-QLKF1pz_yPC-U1HZ1?(M3XUrI|?IVHhz~K{6 z-$*)iMu2S}2D||rQvup4Y5xBnZ2O>s%|tb+{shjJl-qsk8vGfyy>yy($$&W&1|p${N9Az(ta>40TeyfNfs`TvsE=jJ;ISADu}1T8C|44%||M*ji3Pzjul4 z{28{r8n~loy?+}xN78RyV><=gUJl#`WEq-N@0b1Y&wXG!1KYj;c)SMtalwAq7q%0y z?S;TIKz37;>N8-jq_6wLwhp#E7f1w?ee$IGDmj&;FZ;%}3buV3@G`J(1>{@cEJ+#R zL8_H?*!D@~0Kb2Q;`{QAfMbjc;k&M*-U^LbrTJ z*4J~JMl)^wP*abv?Zl|rG#p*=$7GwhNK#UbQB)J~L)qw8C=$A5Z~W{iq)ne;+rI$& zOu*!{vs_XR`lG5QBm4t!zywXsvX@D^b5z_$;jgY(zhKBSbX4B|%Mf==Tr?T;fWKv|2kJf(LuXf*~G zbVfKEkgCq!ujQcs?vUbEzy*Cm=@C_JF@FN)N%~+YbZg*(J_UFU$b>eja^RmM>60PQ zt%3_W9r{=P!)xtS;x=oI*{)L zT+kbUO*QD3fb+ZTFZBj4=#6=Wum=4!aA8*+#9qM#y%|_vgMP3aEn9D!4gt=0-UY0x zLFbxF+ir~a4lbjd2HX8LnOH8}Ea{3ir|m(&1-*M|xGkvxZIpCvTj;^S1)YXlI{yo5 zKpQ08)CPJ`a6zZ>mNaBe1t_85I!U)TMGp=x=o}~0h�gy--rFo4Q5;F6czQiGZp? z!R?Z&?u6POVl?1_PWvYLSl)`?Rn43i#CPayClpNlo44ctUE3ths~yIQ3r01zVXC3$-ra41Q;jMQ@ P00000NkvXXu0mjfZ0{~? literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable-xxxhdpi/version_top_bg.png b/mylibrary/src/main/res/drawable-xxxhdpi/version_top_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..e462198cb0853305f47d342c7d06ce87b727a84f GIT binary patch literal 164954 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

nb`9afjvqdxg+r-nL>^+qh1bn$& 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ɨ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%0D5-zhj8Yt@8iz zR++~$9sD;J;4+;1&xUk45&s`g#LLNdIr%Qr%)iry%LMB0k+_VK|FbV#CQz3N)a81( zTo0F7<7L)(3CsVhJaKs_ULJ~?T;ej9xXdLkbBRmx`vtmsiLzg! z?3XC}e*)*r^>Dc!F4x25dbq4QU1o}xnc`)pc$q0)W{Q`Y;$^0IDTx0&FSsnVU6$G| zOKtzjkS^E5<$C!4^?Im5?k)FBjWdg0=szSn&^#2E+|% z5Hct58k>;2|F2s$1b;vKpXGCn%e9{dGb1Nt=Kme})CH0^j#cdH>%o z!L+evZ`%2wOz2nIV&da}Tj>1zBFV+`uz`*xQQ)=G)T0(1Qt^y`UZ}jzTxs>_fte3< z&EICRxwm+N^S|?}zpmC*4Yg(Bc)A~k+^ZM*h3zp8?xG0)U%t-{Us_bC7F{j7V}rw5 z`5CWv_MVUWLZs;bcFS&V&-FCflvD>sZxa zB)e(1LCYWN$b@lDO9h5>(a|-8PxT)Yz%>YVW@+PW$%Sj8hdIgn8OZ?Yw z|7+r6MaU0dRF9U){%Yv=yZGGF^wid@RH@SUF%9hheDx94VS1|XhevBWA&^m7i@>9v zDH)-$Y&m|d`~SQMYS{Hj)7(dnr>Cl8(mNz*BD_tnMyBl41LO8|Pp*IbM%1qx+fWgC`9Cw{-&g4K49j+s?Yn0X-j#6+vB5UF&pDdi*P{_``qAy5KODzq@muQA;+@&1 z24=6-i#uD}+p|wK--<8uk9!3|L2=HkZCb2LJo~|)WjEsAUfi*1U?zwOxkzp(F>3wu zj+Nq^S=h|fjQTC7fC+EsA$vVMrn4c_xfzdaRx1Q zZ8*z6?t{4Q+~7t`ajI|sqqXuoS`AZfwlo+%V=Lg!JJ@Vyq%vis@;V%`{^NZf1skC}irt$|jvB?P1bESFRt8vX{k=u5$*k-XN z)pxpQN>->WD>d1e7c}sF$`t>5U-qz;K%jV3vWbd#V(_jN$dqUPY zxgqOsBiqgJXl&l7P2~Tx)1lmNZWpHdR-Hb;TAG|QU4IhTy=s}_0RsN1Drw#=RYW}f EKkr-aPyhe` literal 0 HcmV?d00001 diff --git a/mylibrary/src/main/res/drawable/bnav_shape_du.xml b/mylibrary/src/main/res/drawable/bnav_shape_du.xml new file mode 100644 index 0000000..28f5f8d --- /dev/null +++ b/mylibrary/src/main/res/drawable/bnav_shape_du.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/bnav_tab_background.xml b/mylibrary/src/main/res/drawable/bnav_tab_background.xml new file mode 100644 index 0000000..270a701 --- /dev/null +++ b/mylibrary/src/main/res/drawable/bnav_tab_background.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/loading.xml b/mylibrary/src/main/res/drawable/loading.xml new file mode 100644 index 0000000..0ab50a0 --- /dev/null +++ b/mylibrary/src/main/res/drawable/loading.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/select_check_node.xml b/mylibrary/src/main/res/drawable/select_check_node.xml new file mode 100644 index 0000000..1cec8b6 --- /dev/null +++ b/mylibrary/src/main/res/drawable/select_check_node.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/select_sim_text.xml b/mylibrary/src/main/res/drawable/select_sim_text.xml new file mode 100644 index 0000000..d16b429 --- /dev/null +++ b/mylibrary/src/main/res/drawable/select_sim_text.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/select_slide_title.xml b/mylibrary/src/main/res/drawable/select_slide_title.xml new file mode 100644 index 0000000..bf8e084 --- /dev/null +++ b/mylibrary/src/main/res/drawable/select_slide_title.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/select_text_c.xml b/mylibrary/src/main/res/drawable/select_text_c.xml new file mode 100644 index 0000000..5a4b510 --- /dev/null +++ b/mylibrary/src/main/res/drawable/select_text_c.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shadow_bg.9.png b/mylibrary/src/main/res/drawable/shadow_bg.9.png new file mode 100644 index 0000000000000000000000000000000000000000..6dd444226dfd8bb5793005a04de6560977a8b294 GIT binary patch literal 1736 zcmV;(1~>VMP)&!6vq+kh}hOzMG-3?r68bzL?A@1q!P-GCZG)o1R+645slHz8-69cC2f-?WkJF} zP^BBfT3L12x`01GA)z6_qAXBC7timf_dNT0XNGw#{qg1`C-2RhnRCzgo}c%=yJ*q; zP*j0yhoUHYDam0NE}l(J%J#>eRZ0RF9v*&K*SafLuDk;4K6mNTrB`9yFL@D8$jKqw z#`+(quh)#ov&IAv1|1j}c&)#`|MegU8VZHN8>dg7epBB!pE+~pEm-$&&y@K;@{p^~ z^^B!!PFxonKwr<)l(b9?MxU388$$POP#_6RhRzog=T@K1B^nvlxl7Xqmw$dP$|6{r3Pkh*hudexHf6Oitn&5Fe{V_ zSnP(nHd7Z0u7Uk_zB`KPP*q@&Wkb3QOYw9Vd*p_{_`oEfayW5;Fj|&NmwKv($eE^Us#r?Dlk3(Ox%=6 z97kDC`NFb9ser|WS-{%#!wy}K3D{jV5ZM^jOg0e<|+e7KB)ZI@3#*b_kPWpnfM)9%*V>}la=EST3!_2;*EYbM*_*24# zu&K1rECFT#dCC`-B_gqr;4IO#mD?JqRbY1n=m@2WEja1k6i)6fPN`!x1&roFIv%8% zu%@DPm#P+l(eBA&-_ZWqGOM9vU$GW}(V$Dmz0!3v8>Tey;pF~(?E)j!$HiG$aaq|d z?pg!(`0?ZW`O2H6P;CM$7K>M<-#+nHaf|eBOvG1h0;4cXx8s4^DBZ}4KXfl2lkdlB z4;U{($cEBy2U~>FxhZzTs8)foY1`M=_XF0Fj++EM2ch8Ij8SCzE-n{uME-3z-rk4~??J8rfslbv8OQ><=>EL`<3cbpwjHk_)~cx`wx$3&!Mt@g?YK zB=KEYYrFVsf1vpytVH%BQ4mw+ej8&@_WHOEgGAMU#jlSrvxI#@yP~DRpZ=h8Npuue ze2-%#i}kI9hq+%GP|zf>c#E3^!ukfQapVASn!$g4C0>MBB(k1j=|PuHLz{QK-{HV@ z6aeBC7OuC-iZC%n=B@?`a=;*dj5|tT1NDJf0vwjZEg7`n4w0b1v=5;e_Y~Y=7FNDT zb$=-DitS#;5w~knKgI1RzUV>RTjxHJC{loeCV}x|n~f#Jnh9NlTLQ4)R;px6iet&K zplWOrge5qB)PcN$TO_ibzBzDvEv>q?*dZBeR6Y8{r`^yo1*oZHz_8i`I1SK%TUyMm zWKgRgGd}1QxZNbm$yz2&yqZO#9gJCKU~svmWNH8Sp09Ii^1$URQ0ohJL=T{$+nAgY z^M8}kj6CErfw&rD#bClj9K8^rB*nrIoH*?^CkHCw7)a7Gvj(Od#RDXP&L;cv{qg6T e$Szstiu506zvr=S9@Cfr0000 + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shape_bind_phone_background.xml b/mylibrary/src/main/res/drawable/shape_bind_phone_background.xml new file mode 100644 index 0000000..270e9f0 --- /dev/null +++ b/mylibrary/src/main/res/drawable/shape_bind_phone_background.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shape_blue_bg10.xml b/mylibrary/src/main/res/drawable/shape_blue_bg10.xml new file mode 100644 index 0000000..a9bae1b --- /dev/null +++ b/mylibrary/src/main/res/drawable/shape_blue_bg10.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shape_blue_bg25.xml b/mylibrary/src/main/res/drawable/shape_blue_bg25.xml new file mode 100644 index 0000000..cdccedf --- /dev/null +++ b/mylibrary/src/main/res/drawable/shape_blue_bg25.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shape_blue_bg4.xml b/mylibrary/src/main/res/drawable/shape_blue_bg4.xml new file mode 100644 index 0000000..dd388ad --- /dev/null +++ b/mylibrary/src/main/res/drawable/shape_blue_bg4.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shape_blue_bg8.xml b/mylibrary/src/main/res/drawable/shape_blue_bg8.xml new file mode 100644 index 0000000..6e7e086 --- /dev/null +++ b/mylibrary/src/main/res/drawable/shape_blue_bg8.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shape_bottom_bgw16.xml b/mylibrary/src/main/res/drawable/shape_bottom_bgw16.xml new file mode 100644 index 0000000..ad939cf --- /dev/null +++ b/mylibrary/src/main/res/drawable/shape_bottom_bgw16.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shape_gray_bg10.xml b/mylibrary/src/main/res/drawable/shape_gray_bg10.xml new file mode 100644 index 0000000..4a9a9e5 --- /dev/null +++ b/mylibrary/src/main/res/drawable/shape_gray_bg10.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shape_gray_bg25.xml b/mylibrary/src/main/res/drawable/shape_gray_bg25.xml new file mode 100644 index 0000000..bb01f39 --- /dev/null +++ b/mylibrary/src/main/res/drawable/shape_gray_bg25.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shape_gray_bg4.xml b/mylibrary/src/main/res/drawable/shape_gray_bg4.xml new file mode 100644 index 0000000..7ed2a61 --- /dev/null +++ b/mylibrary/src/main/res/drawable/shape_gray_bg4.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shape_log_btn_bg22.xml b/mylibrary/src/main/res/drawable/shape_log_btn_bg22.xml new file mode 100644 index 0000000..6a526c2 --- /dev/null +++ b/mylibrary/src/main/res/drawable/shape_log_btn_bg22.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shape_message.xml b/mylibrary/src/main/res/drawable/shape_message.xml new file mode 100644 index 0000000..f70d586 --- /dev/null +++ b/mylibrary/src/main/res/drawable/shape_message.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shape_text_4_blue.xml b/mylibrary/src/main/res/drawable/shape_text_4_blue.xml new file mode 100644 index 0000000..9d7ac38 --- /dev/null +++ b/mylibrary/src/main/res/drawable/shape_text_4_blue.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shape_text_4_nor.xml b/mylibrary/src/main/res/drawable/shape_text_4_nor.xml new file mode 100644 index 0000000..9389c1b --- /dev/null +++ b/mylibrary/src/main/res/drawable/shape_text_4_nor.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/shape_view_v.xml b/mylibrary/src/main/res/drawable/shape_view_v.xml new file mode 100644 index 0000000..d59ee95 --- /dev/null +++ b/mylibrary/src/main/res/drawable/shape_view_v.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/drawable/white_round_corner_bg.xml b/mylibrary/src/main/res/drawable/white_round_corner_bg.xml new file mode 100644 index 0000000..d330d5b --- /dev/null +++ b/mylibrary/src/main/res/drawable/white_round_corner_bg.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/layout/common_toolbar.xml b/mylibrary/src/main/res/layout/common_toolbar.xml new file mode 100644 index 0000000..ce88b6e --- /dev/null +++ b/mylibrary/src/main/res/layout/common_toolbar.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/mylibrary/src/main/res/layout/custom_dialog_two_layout.xml b/mylibrary/src/main/res/layout/custom_dialog_two_layout.xml new file mode 100644 index 0000000..bb372d4 --- /dev/null +++ b/mylibrary/src/main/res/layout/custom_dialog_two_layout.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + diff --git a/mylibrary/src/main/res/layout/empty_pic.xml b/mylibrary/src/main/res/layout/empty_pic.xml new file mode 100644 index 0000000..52b216b --- /dev/null +++ b/mylibrary/src/main/res/layout/empty_pic.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + diff --git a/mylibrary/src/main/res/layout/gv_filter_image.xml b/mylibrary/src/main/res/layout/gv_filter_image.xml new file mode 100644 index 0000000..3a5194e --- /dev/null +++ b/mylibrary/src/main/res/layout/gv_filter_image.xml @@ -0,0 +1,46 @@ + + + + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/layout/item_car_select.xml b/mylibrary/src/main/res/layout/item_car_select.xml new file mode 100644 index 0000000..414e97c --- /dev/null +++ b/mylibrary/src/main/res/layout/item_car_select.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/layout/item_dic_select.xml b/mylibrary/src/main/res/layout/item_dic_select.xml new file mode 100644 index 0000000..9e94d4c --- /dev/null +++ b/mylibrary/src/main/res/layout/item_dic_select.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/layout/item_node_select.xml b/mylibrary/src/main/res/layout/item_node_select.xml new file mode 100644 index 0000000..396acb0 --- /dev/null +++ b/mylibrary/src/main/res/layout/item_node_select.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/layout/item_select.xml b/mylibrary/src/main/res/layout/item_select.xml new file mode 100644 index 0000000..56a9f34 --- /dev/null +++ b/mylibrary/src/main/res/layout/item_select.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/layout/my_confim_popup_input.xml b/mylibrary/src/main/res/layout/my_confim_popup_input.xml new file mode 100644 index 0000000..db788f2 --- /dev/null +++ b/mylibrary/src/main/res/layout/my_confim_popup_input.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/layout/my_confim_popup_tip.xml b/mylibrary/src/main/res/layout/my_confim_popup_tip.xml new file mode 100644 index 0000000..366f7cf --- /dev/null +++ b/mylibrary/src/main/res/layout/my_confim_popup_tip.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + diff --git a/mylibrary/src/main/res/layout/view_slide_bar.xml b/mylibrary/src/main/res/layout/view_slide_bar.xml new file mode 100644 index 0000000..80483e7 --- /dev/null +++ b/mylibrary/src/main/res/layout/view_slide_bar.xml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mylibrary/src/main/res/values/attrs.xml b/mylibrary/src/main/res/values/attrs.xml new file mode 100644 index 0000000..6af9f09 --- /dev/null +++ b/mylibrary/src/main/res/values/attrs.xml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/values/colors.xml b/mylibrary/src/main/res/values/colors.xml new file mode 100644 index 0000000..2a87706 --- /dev/null +++ b/mylibrary/src/main/res/values/colors.xml @@ -0,0 +1,30 @@ + + + #28B950 + #28B950 + #D81B60 + + #FFFFFFFF + #333333 + #666666 + #FE0606 + #ff007aff + #3C6FC6 + #88888888 + + + + + #F5F5F5 + #000000 + #E6E6E6 + #F7F7F7 + #999999 + #f6f6f6 + #D5D9DB + + + + + + diff --git a/mylibrary/src/main/res/values/dimens.xml b/mylibrary/src/main/res/values/dimens.xml new file mode 100644 index 0000000..003e401 --- /dev/null +++ b/mylibrary/src/main/res/values/dimens.xml @@ -0,0 +1,26 @@ + + + 8sp + 9sp + 10sp + 11sp + 12sp + 13sp + 14sp + 15sp + 16sp + 17sp + 18sp + 19sp + 20sp + 21sp + 22sp + 23sp + 24sp + 26sp + 28sp + 30sp + 40sp + 56dp + 40dp + diff --git a/mylibrary/src/main/res/values/ids.xml b/mylibrary/src/main/res/values/ids.xml new file mode 100644 index 0000000..efaf17b --- /dev/null +++ b/mylibrary/src/main/res/values/ids.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/mylibrary/src/main/res/values/strings.xml b/mylibrary/src/main/res/values/strings.xml new file mode 100644 index 0000000..708d45e --- /dev/null +++ b/mylibrary/src/main/res/values/strings.xml @@ -0,0 +1,7 @@ + + CommonBaseLibrary + + 拍照 + 从相册中选择 + 取消 + diff --git a/mylibrary/src/main/res/values/styles.xml b/mylibrary/src/main/res/values/styles.xml new file mode 100644 index 0000000..6c47106 --- /dev/null +++ b/mylibrary/src/main/res/values/styles.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mylibrary/src/test/java/com/dahe/mylibrary/ExampleUnitTest.kt b/mylibrary/src/test/java/com/dahe/mylibrary/ExampleUnitTest.kt new file mode 100644 index 0000000..0e4dd1d --- /dev/null +++ b/mylibrary/src/test/java/com/dahe/mylibrary/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.dahe.mylibrary + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} \ No newline at end of file